MST

星途 面试题库

面试题:Flutter自定义Widget的设计思路与实践

假设要设计一个可复用的卡片式Widget,该Widget需要包含图片、标题、描述信息,且能自适应不同屏幕尺寸。请阐述你的设计思路,包括如何处理布局、样式以及交互逻辑,写出核心代码示例。
25.5万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 布局
    • 使用响应式布局框架,例如Flutter中的LayoutBuilder或React Native中的Dimensions结合Flexbox布局,以便根据屏幕尺寸动态调整卡片的大小和位置。
    • 在卡片内部,采用垂直布局(例如Flutter中的Column或React Native中的View结合flexDirection: 'column')来依次放置图片、标题和描述信息。
  2. 样式
    • 为图片设置合适的widthheight,可以使用BoxFit(Flutter)或类似的属性(React Native)来确保图片在不同尺寸屏幕上的显示效果。
    • 标题和描述信息设置合适的字体大小、颜色和行间距,通过媒体查询(如CSS中的@media,Flutter和React Native也有类似机制)根据屏幕尺寸调整这些样式。
  3. 交互逻辑
    • 可以为整个卡片添加点击事件,例如在Flutter中使用GestureDetector,React Native中使用TouchableOpacity,以实现卡片被点击后的导航或其他交互操作。

核心代码示例(以Flutter为例)

import 'package:flutter/material.dart';

class CardWidget extends StatelessWidget {
  final String imageUrl;
  final String title;
  final String description;

  const CardWidget({
    Key? key,
    required this.imageUrl,
    required this.title,
    required this.description,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        return GestureDetector(
          onTap: () {
            // 处理点击事件
          },
          child: Container(
            margin: const EdgeInsets.all(16),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(10),
              color: Colors.white,
              boxShadow: [
                BoxShadow(
                  color: Colors.grey.withOpacity(0.5),
                  spreadRadius: 2,
                  blurRadius: 5,
                  offset: const Offset(0, 3),
                ),
              ],
            ),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Image.network(
                  imageUrl,
                  width: double.infinity,
                  height: constraints.maxWidth * 0.6,
                  fit: BoxFit.cover,
                ),
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text(
                        title,
                        style: const TextStyle(
                          fontSize: 20,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      const SizedBox(height: 8),
                      Text(
                        description,
                        style: const TextStyle(fontSize: 16),
                        maxLines: 3,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

使用示例

void main() {
  runApp(MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: const Text('Card Example')),
      body: ListView(
        children: [
          CardWidget(
            imageUrl: 'https://example.com/image.jpg',
            title: '示例标题',
            description: '这是一段示例描述信息,用于展示卡片的内容。',
          ),
        ],
      ),
    ),
  ));
}