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

在Flutter中不使用外部包实现带双色边框按钮的内阴影效果

在Flutter中不使用外部包实现带双色边框按钮的内阴影效果

嘿,我明白你想要实现的效果啦——给这个带双色渐变边框的按钮加上和边框同色的内阴影,还不想依赖第三方包对吧?完全没问题,咱们用Flutter原生的组件就能搞定!

首先得说明:Flutter的BoxDecoration本身并没有直接的内阴影(inner shadow)属性,但我们可以通过叠加渐变遮罩的方式模拟这个效果,让遮罩的渐变颜色和按钮边框的渐变保持一致,这样视觉上就会呈现出和边框同色的内阴影啦。

思路分析

你的原代码是用两层Container嵌套实现的:外层是带渐变边框的容器,内层是深色背景的按钮主体。现在要加内阴影,我们只需要在内层容器上叠加一层非常薄的渐变层——这个渐变层的边缘用边框的渐变颜色(带透明度),向内过渡到完全透明,这样就会产生“阴影向内”的视觉效果。

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:taskk/second_screen.dart';

class HomeScreen extends StatelessWidget {
  HomeScreen({super.key});

  final kInnerDecoration = BoxDecoration(
    color: Color(0xFF18181B),
    border: Border.all(color: Color(0xFF18181B)),
    borderRadius: BorderRadius.circular(32),
  );

  final kGradientBoxDecoration = BoxDecoration(
    gradient: LinearGradient(colors: [Color(0xFF2EB0CA), Color(0xFF8F56A4)]),
    border: Border.all(
      color: Color(0xFF18181B),
    ),
    borderRadius: BorderRadius.circular(32),
  );

  // 定义上下方向的内阴影渐变(匹配边框渐变方向)
  final kInnerShadowVerticalDecoration = BoxDecoration(
    borderRadius: BorderRadius.circular(32),
    gradient: LinearGradient(
      begin: Alignment.topCenter,
      end: Alignment.bottomCenter,
      colors: [
        Color(0xFF2EB0CA).withOpacity(0.25), // 顶部阴影用边框左色,带透明度
        Colors.transparent,
        Colors.transparent,
        Color(0xFF8F56A4).withOpacity(0.25), // 底部阴影用边框右色,带透明度
      ],
      stops: [0.0, 0.02, 0.98, 1.0], // 控制阴影厚度,0.02表示仅占边缘2%区域
    ),
  );

  // 定义左右方向的内阴影渐变
  final kInnerShadowHorizontalDecoration = BoxDecoration(
    borderRadius: BorderRadius.circular(32),
    gradient: LinearGradient(
      begin: Alignment.centerLeft,
      end: Alignment.centerRight,
      colors: [
        Color(0xFF2EB0CA).withOpacity(0.25),
        Colors.transparent,
        Colors.transparent,
        Color(0xFF8F56A4).withOpacity(0.25),
      ],
      stops: [0.0, 0.02, 0.98, 1.0],
    ),
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            InkWell(
              onTap: () => Navigator.pushReplacement(
                context,
                MaterialPageRoute(
                  builder: (context) => Second(),
                ),
              ),
              child: Container(
                width: 221,
                height: 43.0,
                decoration: kGradientBoxDecoration,
                child: Padding(
                  padding: const EdgeInsets.all(2.0),
                  // 用Stack叠加背景、阴影和文字,保证层级正确
                  child: Stack(
                    fit: StackFit.expand,
                    children: [
                      // 原始深色背景容器
                      Container(decoration: kInnerDecoration),
                      // 上下方向内阴影
                      Container(decoration: kInnerShadowVerticalDecoration),
                      // 左右方向内阴影
                      Container(decoration: kInnerShadowHorizontalDecoration),
                      // 按钮文字(放在最上层)
                      Center(
                        child: Text(
                          "Enter now",
                          style: TextStyle(
                              fontWeight: FontWeight.w700, fontSize: 16),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

关键细节说明

  • 渐变参数调整:通过stops参数控制阴影的厚度,0.02表示阴影仅占据容器边缘2%的区域,让阴影细腻不厚重;
  • 透明度控制:给边框颜色添加withOpacity(0.25),让阴影看起来自然柔和,不会和边框产生冲突;
  • Stack层级管理:用Stack把背景、两层阴影和文字叠加,保证文字在最上层,阴影在背景之上、文字之下,视觉层级正确。

如果你想要更明显或更淡的阴影,只需要调整opacity的值或者stops的参数就可以啦~

备注:内容来源于stack exchange,提问作者Ahmed Alagha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 08:09:33