Flutter如何为BoxDecoration添加平铺图片实现滑块格纹背景
Flutter alpha滑块添加棋盘格背景实现方案
你可以直接通过BoxDecoration叠加两层效果实现需求,无需手动处理ImageShader,代码更简洁,也能自动适配动态滑块尺寸:
实现步骤
- 准备小尺寸棋盘格PNG资源(推荐尺寸20x20像素,黑白交错格),放入项目assets资源目录,在pubspec.yaml中声明资源:
flutter: assets: - assets/checkerboard.png
- 修改原滑块代码,在BoxDecoration中先添加平铺的棋盘格背景,再叠加原有alpha渐变即可,Container设置的圆角会自动裁剪背景内容,无需额外处理:
gradient = LinearGradient( colors: colors, begin: Alignment.topCenter, end: Alignment.bottomCenter ); Widget content = Positioned( left: left, top: top, child: Container( width: barWidth, height: barHeight, decoration: BoxDecoration( border: Border.all(color: Colors.black), borderRadius: BorderRadius.all(Radius.circular(10)), // 底层棋盘格背景,自动平铺适配任意尺寸 image: DecorationImage( image: AssetImage('assets/checkerboard.png'), repeat: ImageRepeat.repeat, ), // 上层alpha渐变,半透明区域会自动透出棋盘格 gradient: gradient, ), ), );
无外部资源方案(纯代码绘制棋盘格)
如果不想引入外部图片资源,可以用CustomPaint自绘棋盘格作为底层,同样支持动态尺寸适配:
// 棋盘格绘制类 class CheckerboardPainter extends CustomPainter { final double gridSize; CheckerboardPainter({this.gridSize = 10}); @override void paint(Canvas canvas, Size size) { final Paint paint1 = Paint()..color = const Color(0xFFEEEEEE); final Paint paint2 = Paint()..color = const Color(0xFFCCCCCC); for (int i = 0; i < size.width / gridSize; i++) { for (int j = 0; j < size.height / gridSize; j++) { final isOdd = (i + j) % 2 == 1; canvas.drawRect( Rect.fromLTWH(i * gridSize, j * gridSize, gridSize, gridSize), isOdd ? paint2 : paint1, ); } } } @override bool shouldRepaint(covariant CheckerboardPainter oldDelegate) { return oldDelegate.gridSize != gridSize; } } // 滑块代码修改为 gradient = LinearGradient( colors: colors, begin: Alignment.topCenter, end: Alignment.bottomCenter ); Widget content = Positioned( left: left, top: top, child: Container( width: barWidth, height: barHeight, decoration: BoxDecoration( border: Border.all(color: Colors.black), borderRadius: BorderRadius.all(Radius.circular(10)), ), child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(10)), child: Stack( children: [ // 底层棋盘格 CustomPaint( size: Size(barWidth, barHeight), painter: CheckerboardPainter(gridSize: 10), ), // 上层alpha渐变 Container( decoration: BoxDecoration( gradient: gradient, ), ) ], ), ), ), );
ImageShader实现方案
如果你确实需要使用ImageShader实现,需要先异步加载解码图片资源,再通过DecorationImage的shader属性传入即可,核心逻辑如下:
import 'dart:ui' as ui; // 预加载图片转换成ImageShader Future<Shader> loadCheckerboardShader() async { final ByteData data = await rootBundle.load('assets/checkerboard.png'); final Uint8List bytes = data.buffer.asUint8List(); final ui.Image image = await decodeImageFromList(bytes); return ImageShader( image, TileMode.repeated, TileMode.repeated, Matrix4.identity().storage, ); } // 使用时通过FutureBuilder获取shader后传入 Shader? checkerboardShader; // 加载完成后赋值给checkerboardShader,再在decoration中使用 decoration: BoxDecoration( border: Border.all(color: Colors.black), borderRadius: BorderRadius.all(Radius.circular(10)), shader: checkerboardShader, gradient: gradient, )
内容的提问来源于stack exchange,提问作者Jason Bullen
相关产品推荐
相关产品推荐

