MST

星途 面试题库

面试题:Flutter中如何通过Widget组合实现可复用的复杂卡片UI

在Flutter开发中,要求你构建一个可复用的复杂卡片UI,卡片包含图片、标题、描述以及底部操作按钮。请描述实现思路,并给出关键代码示例,说明如何利用Widget组合来提高代码的可维护性和复用性。
36.7万 热度难度
前端开发Flutter

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 创建基础卡片结构:使用 Card 组件作为整体容器,它提供了默认的圆角和阴影效果。
  2. 添加图片:使用 Image 组件或 CachedNetworkImage(如果图片来自网络)来显示图片,并设置合适的尺寸和裁剪方式。
  3. 添加标题和描述:使用 Text 组件分别显示标题和描述,通过 TextStyle 控制文本样式,如字体大小、颜色等。
  4. 添加底部操作按钮:使用 RowColumn 来排列操作按钮,按钮可使用 ElevatedButtonTextButton 等。
  5. 利用Widget组合:将卡片中的各个部分封装成独立的 Widget,然后在主卡片 Widget 中进行组合,这样可以提高代码的可维护性和复用性。

关键代码示例

import 'package:flutter/material.dart';

// 自定义图片显示Widget
class CustomCardImage extends StatelessWidget {
  final String imageUrl;
  const CustomCardImage({required this.imageUrl, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Image.network(
      imageUrl,
      width: double.infinity,
      height: 200,
      fit: BoxFit.cover,
    );
  }
}

// 自定义标题显示Widget
class CustomCardTitle extends StatelessWidget {
  final String title;
  const CustomCardTitle({required this.title, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text(
      title,
      style: const TextStyle(
        fontSize: 20,
        fontWeight: FontWeight.bold,
      ),
    );
  }
}

// 自定义描述显示Widget
class CustomCardDescription extends StatelessWidget {
  final String description;
  const CustomCardDescription({required this.description, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text(
      description,
      style: const TextStyle(
        fontSize: 16,
      ),
    );
  }
}

// 自定义操作按钮Widget
class CustomCardActions extends StatelessWidget {
  final List<Widget> actions;
  const CustomCardActions({required this.actions, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: actions,
    );
  }
}

// 主卡片Widget
class ComplexCard extends StatelessWidget {
  final String imageUrl;
  final String title;
  final String description;
  final List<Widget> actions;

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

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          CustomCardImage(imageUrl: imageUrl),
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                CustomCardTitle(title: title),
                const SizedBox(height: 8),
                CustomCardDescription(description: description),
                const SizedBox(height: 16),
                CustomCardActions(actions: actions),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

使用示例

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Complex Card Example'),
        ),
        body: Center(
          child: ComplexCard(
            imageUrl: 'https://example.com/image.jpg',
            title: 'Card Title',
            description: 'This is a description of the card.',
            actions: [
              ElevatedButton(
                onPressed: () {},
                child: const Text('Button 1'),
              ),
              ElevatedButton(
                onPressed: () {},
                child: const Text('Button 2'),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}

通过以上方式,将卡片的各个部分拆分成独立的 Widget,在 ComplexCard 中进行组合,提高了代码的可维护性和复用性。例如,如果需要修改图片的加载方式或者标题的样式,只需在对应的 CustomCardImageCustomCardTitle 中进行修改,而不会影响其他部分。