痛点:
在Flutter 系统给出的组件中,TabBar 是一个非常好用的插件,但是一直困扰我的是他的指示器参数只能写一下颜色 或者圆角之类的,不能满足自定义 图片的内容。
解决方案:
我们看源码中 indicator 的类型是 Decoration 但是,是一个抽象接口 我们需要看 BoxDecoration 我们找到 有 返回 BoxPainter 的方法
@override
BoxPainter createBoxPainter([ VoidCallback? onChanged ]) {
assert(onChanged != null || image == null);
return _BoxDecorationPainter(this, onChanged);
}
我们再来看 BoxPainter 。
从字面意思看,大概是盒子绘制者。
我们发现 BoxPainter 是一个抽象层 定义了一个这样的一个绘制的方法。
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration);
接下来我们就可以继承 :BoxDecoration 并实现下面方法:
BoxPainter createBoxPainter([ VoidCallback? onChanged ])
然后,继承 BoxPaiter 虚拟类 并实现如下方法:
paint(Canvas canvas, Offset offset, ImageConfiguration configuration);
在此方法中利用 Canvas 进行我们需要的绘制 。
这里需要说明一下,加载本地图片绘制是异步过程。
下面是如何加载本地assets 资源图片的过程:
import 'dart:async';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
/// 当使用 CustomPaint 或者自定义 shape 的时候 需要一个 绘制一张图片时候需要这样加载
class PaintImageTool {
// 通过本地路径拿到图片
static Future<ui.Image> getAssetImage(String asset,{width,height}) async {
ByteData data = await rootBundle.load(asset);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),targetWidth: width,targetHeight: height);
ui.FrameInfo fi = await codec.getNextFrame();
return fi.image;
}
static Future<ui.Image> getAssetImage2(String asset,BuildContext context,{width,height}) async {
ByteData data = await DefaultAssetBundle.of(context).load(asset);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),targetWidth: width,targetHeight: height);
ui.FrameInfo fi = await codec.getNextFrame();
return fi.image;
}
//方法1:获取网络图片 返回ui.Image
static Future<ui.Image> getNetImage(String url,{width,height}) async {
ByteData data = await NetworkAssetBundle(Uri.parse(url)).load(url);
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),targetWidth: width,targetHeight: height);
ui.FrameInfo fi = await codec.getNextFrame();
return fi.image;
}
}
最后和TabBarView 配合联动效果如下:
注意事项: 绘图 绘制的都是 1 倍像素的 会看到有毛边现象。
具体解决方法如下:
canvas.drawImageRect(Image image, Rect src, Rect dst, Paint paint)
image 通过上面方法加载的图片内容。
src 表示图片上的像素点剪切的位置; 使用原始像素范围
dst 表示要绘制到什么位置,以及大小的参数。 压缩原始像素尺寸 例如宽高缩小3倍
paint 绘制参数
想必看到这里聪明的你应该理解我的意思了,那么赶紧试试吧!希望你能成功。