在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
相关产品推荐
相关产品推荐

