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

Flutter如何为BoxDecoration添加平铺图片实现滑块格纹背景

Flutter alpha滑块添加棋盘格背景实现方案

你可以直接通过BoxDecoration叠加两层效果实现需求,无需手动处理ImageShader,代码更简洁,也能自动适配动态滑块尺寸:

实现步骤

  1. 准备小尺寸棋盘格PNG资源(推荐尺寸20x20像素,黑白交错格),放入项目assets资源目录,在pubspec.yaml中声明资源:
flutter:
  assets:
    - assets/checkerboard.png
  1. 修改原滑块代码,在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:45:08