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

如何在Flutter中实现符合设计图的自定义按钮?

问题描述

我尝试实现下图所示的UI设计,但未能创建出外观和质感与设计图一致的按钮。

目标按钮UI设计

当前实现代码

ElevatedButton(
  child: Row(
    children: [
      Text("A:",style: TextStyle(fontSize: 15,color: Colors.yellowAccent)),
      Spacer(),
      Text("Butterfly",style: TextStyle(fontSize: 16,color: Colors.yellowAccent,fontWeight: FontWeight.bold)),
      Spacer(),
    ],),
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.deepPurpleAccent,
    shape: StadiumBorder(),
  ),
  onPressed: (){},
),
ElevatedButton(
  child: Row(
    children: [
      Text("B:",style: TextStyle(fontSize: 15,color: Colors.yellowAccent)),
      Spacer(),
      Text("Ant",style: TextStyle(fontSize: 16,color: Colors.yellowAccent,fontWeight: FontWeight.bold)),
      Spacer(),
    ],),
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.deepPurpleAccent,
    shape: StadiumBorder(),
  ),
  onPressed: (){},
),
ElevatedButton(
  child: Row(
    children: [
      Text("C:",style: TextStyle(fontSize: 15,color: Colors.yellowAccent)),
      Spacer(),
      Text("Scorpion",style: TextStyle(fontSize: 16,color: Colors.yellowAccent,fontWeight: FontWeight.bold)),
      Spacer(),
    ],),
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.deepPurpleAccent,
    shape: StadiumBorder(),
  ),
  onPressed: (){},
),
ElevatedButton(
  child: Row(
    children: [
      Text("D:",style: TextStyle(fontSize: 15,color: Colors.yellowAccent)),
      Spacer(),
      Text("Bee",style: TextStyle(fontSize: 16,color: Colors.yellowAccent,fontWeight: FontWeight.bold)),
      Spacer(),
    ],),
  style: ElevatedButton.styleFrom(
    backgroundColor: Colors.deepPurpleAccent,
    shape: StadiumBorder(),
  ),
  onPressed: (){},
),

优化实现方案

针对设计图的渐变背景、立体阴影和文本布局,调整代码如下:

修改后完整代码

// 提取复用样式,减少冗余代码
final buttonGradient = LinearGradient(
  colors: [Colors.deepPurple.shade700, Colors.deepPurpleAccent],
  begin: Alignment.topLeft,
  end: Alignment.bottomRight,
);

final labelStyle = TextStyle(fontSize: 15, color: Colors.yellowAccent);
final valueStyle = TextStyle(fontSize: 16, color: Colors.yellowAccent, fontWeight: FontWeight.bold);

Column(
  children: [
    ElevatedButton(
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text("A:", style: labelStyle),
            Text("Butterfly", style: valueStyle),
          ],
        ),
      ),
      style: ElevatedButton.styleFrom(
        elevation: 8,
        shadowColor: Colors.deepPurple.withOpacity(0.5),
        shape: StadiumBorder(),
        backgroundColor: Colors.transparent,
        padding: EdgeInsets.zero,
      ).copyWith(
        backgroundColor: MaterialStateProperty.all(Colors.transparent),
        overlayColor: MaterialStateProperty.all(Colors.white.withOpacity(0.1)),
        surfaceTintColor: MaterialStateProperty.all(Colors.transparent),
      ),
      onPressed: () {},
    ),
    SizedBox(height: 8),
    ElevatedButton(
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text("B:", style: labelStyle),
            Text("Ant", style: valueStyle),
          ],
        ),
      ),
      style: ElevatedButton.styleFrom(
        elevation: 8,
        shadowColor: Colors.deepPurple.withOpacity(0.5),
        shape: StadiumBorder(),
        backgroundColor: Colors.transparent,
        padding: EdgeInsets.zero,
      ).copyWith(
        backgroundColor: MaterialStateProperty.all(Colors.transparent),
        overlayColor: MaterialStateProperty.all(Colors.white.withOpacity(0.1)),
        surfaceTintColor: MaterialStateProperty.all(Colors.transparent),
      ),
      onPressed: () {},
    ),
    SizedBox(height: 8),
    ElevatedButton(
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text("C:", style: labelStyle),
            Text("Scorpion", style: valueStyle),
          ],
        ),
      ),
      style: ElevatedButton.styleFrom(
        elevation: 8,
        shadowColor: Colors.deepPurple.withOpacity(0.5),
        shape: StadiumBorder(),
        backgroundColor: Colors.transparent,
        padding: EdgeInsets.zero,
      ).copyWith(
        backgroundColor: MaterialStateProperty.all(Colors.transparent),
        overlayColor: MaterialStateProperty.all(Colors.white.withOpacity(0.1)),
        surfaceTintColor: MaterialStateProperty.all(Colors.transparent),
      ),
      onPressed: () {},
    ),
    SizedBox(height: 8),
    ElevatedButton(
      child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text("D:", style: labelStyle),
            Text("Bee", style: valueStyle),
          ],
        ),
      ),
      style: ElevatedButton.styleFrom(
        elevation: 8,
        shadowColor: Colors.deepPurple.withOpacity(0.5),
        shape: StadiumBorder(),
        backgroundColor: Colors.transparent,
        padding: EdgeInsets.zero,
      ).copyWith(
        backgroundColor: MaterialStateProperty.all(Colors.transparent),
        overlayColor: MaterialStateProperty.all(Colors.white.withOpacity(0.1)),
        surfaceTintColor: MaterialStateProperty.all(Colors.transparent),
      ),
      onPressed: () {},
    ),
  ],
)

关键调整点

  1. 渐变背景:用LinearGradient实现深紫到浅紫的渐变,替代原纯色背景
  2. 立体阴影:提高elevation至8,设置半透明阴影颜色,增强按钮层次感
  3. 文本布局:用MainAxisAlignment.spaceBetween让左右文本分别对齐两侧,配合内边距让内容更舒展
  4. 交互反馈:设置overlayColor处理点击时的半透明反馈,保持交互体验
  5. 代码复用:提取渐变和文本样式,减少重复代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 19:10:47