You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter自定义按钮实现求助:复刻Figma设计的首页按钮

实现Figma设计的带SVG图标按钮

1. 添加SVG支持依赖

首先在pubspec.yaml中添加flutter_svg依赖以加载SVG图标:

dependencies:
  flutter:
    sdk: flutter
  flutter_svg: ^2.0.9 # 使用最新版本即可

执行flutter pub get完成依赖安装。

2. 配置SVG资源

将SVG图标文件放入项目assets/icons/目录(例如命名为reminder_icon.svg、news_icon.svg、recipe_icon.svg),然后在pubspec.yaml中声明资源:

flutter:
  assets:
    - assets/icons/

3. 自定义带图标的按钮组件

创建可复用的IconTextButton组件,实现图标在上、文字在下的布局,同时复刻设计中的圆角、阴影样式:

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class IconTextButton extends StatelessWidget {
  final String svgPath;
  final String buttonText;
  final VoidCallback onPressed;
  final Color? backgroundColor;
  final Color? textColor;

  const IconTextButton({
    super.key,
    required this.svgPath,
    required this.buttonText,
    required this.onPressed,
    this.backgroundColor = Colors.white,
    this.textColor = Colors.black87,
  });

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
        backgroundColor: backgroundColor,
        foregroundColor: textColor,
        elevation: 4, // 匹配设计的阴影高度
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12), // 圆角大小
        ),
        padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
        minimumSize: const Size(100, 80),
      ),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          SvgPicture.asset(
            svgPath,
            width: 40,
            height: 40,
            colorFilter: ColorFilter.mode(textColor!, BlendMode.srcIn),
          ),
          const SizedBox(height: 8),
          Text(
            buttonText,
            textAlign: TextAlign.center,
            style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
          ),
        ],
      ),
    );
  }
}

4. 替换原有按钮为自定义组件

修改HomePage代码,用IconTextButton替代普通ElevatedButton,同时优化布局适配:

import 'package:flutter/material.dart';
import 'package:medreminder/NewsArticle/news_home.dart';
import 'package:medreminder/Reminder/ui/home_reminder.dart';

void main() {
  runApp(const HomePage());
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Medicine Reminder App'),
        ),
        body: Column(
          children: [
            Image.asset(
              'images/MenuImg.jpg',
              width: double.infinity, // 适配屏幕宽度
              height: 200,
              fit: BoxFit.cover,
            ),
            const SizedBox(height: 20.0),
            Padding(
              padding: const EdgeInsets.symmetric(horizontal: 16),
              child: Row(
                children: [
                  Expanded(
                    child: IconTextButton(
                      svgPath: 'assets/icons/reminder_icon.svg',
                      buttonText: 'Reminder',
                      onPressed: () {
                        Navigator.of(context, rootNavigator: true).push(
                          MaterialPageRoute(builder: (context) => const ReminderHomePage()),
                        );
                      },
                    ),
                  ),
                  const SizedBox(width: 16),
                  Expanded(
                    child: IconTextButton(
                      svgPath: 'assets/icons/news_icon.svg',
                      buttonText: 'News & Article',
                      onPressed: () {
                        Navigator.of(context, rootNavigator: true).push(
                          MaterialPageRoute(builder: (context) => const NewsHomePage()),
                        );
                      },
                    ),
                  ),
                  const SizedBox(width: 16),
                  Expanded(
                    child: IconTextButton(
                      svgPath: 'assets/icons/recipe_icon.svg',
                      buttonText: 'Healty Food Recipe',
                      onPressed: () {},
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

额外优化说明

  • 将顶部图片宽度设为double.infinity,避免固定宽度导致的适配问题
  • 用Expanded包裹按钮,让三个按钮在屏幕上均匀分配宽度
  • 增加左右内边距,避免按钮贴边影响视觉效果

内容的提问来源于stack exchange,提问作者NyK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:35:28