# Flutter Xfermode 实现
```dart
//设置矩阵变换区域
canvas.saveLayer(Offset.zero& size, Paint());
/// 绘制背景
Rect rect = Rect.fromPoints(start, valueEnd);
canvas.drawLine(start, valueEnd, mPaint);
mPaint.blendMode = BlendMode.srcIn;
/// 绘制进度
mPaint.strokeCap = StrokeCap.square;
/// 增加渐变色
mPaint.shader = LinearGradient(colors: colors).createShader(rect);
//计算进度的长度
valueEnd = valueEnd = Offset(
value *(size.width - 2 * _offset)+ _offset, _offset);
//合成图层
canvas.drawLine(start, valueEnd, mPaint);
canvas.restore();
```
文字反色实现
```dart
/// 绘制反色文字
double fontSize = 10;
double marginTop =(strokeWidth - fontSize)/ 2.0;
start = Offset(_offset, 0); //画笔起点坐标
valueEnd = Offset(value *(size.width - 2 * _offset)+ _offset * 2,
_offset * 2); //计算进度的长度
var textPainter = TextPainter(
text: TextSpan(
text: soldNumString,
style: TextStyle(color: Color(0xffFC5E82), fontSize: fontSize)),
textDirection: TextDirection.ltr,
maxLines: 1,
)..layout();
textPainter.paint(canvas, Offset(marginStart, marginTop));
if(value > 0) {
canvas.saveLayer(Rect.fromPoints(start, valueEnd), Paint());
var textPainter2 = TextPainter(
text: TextSpan(
text: soldNumString,
style: TextStyle(color: ColorCons.white, fontSize: fontSize)),
textDirection: TextDirection.ltr,
maxLines: 1,
)..layout();
// 绘制两次达到Xfermode的效果
textPainter2.paint(canvas, Offset(marginStart, marginTop));
textPainter2.paint(canvas, Offset(marginStart, marginTop));
canvas.restore();
}
```
完整代码
```dart
import 'package:flutter/material.dart';
import 'package:si_basic_flutter/base/cons/color_cons.dart';
class GradientLinearProgressBar extends StatelessWidget{
final double strokeWidth; //画笔的宽度,其实是进度条的高度
final double value; //进度值
final List<Color>colors; //渐变的颜色列表
final Color backgroundColor;
final String soldNumString;
const GradientLinearProgressBar(
{this.strokeWidth = 2.0,
@required this.colors,
@required this.value,
this.backgroundColor,
this.soldNumString = ""});
@override
Widget build(BuildContext context) {
var _colors = colors;
if(_colors == null) {
Color color = Theme.of(context).accentColor;
_colors =[color, color];
}else if(_colors.length == 1) {
var color = _colors[0];
_colors =[color, color];
}
var _backgroundColor = backgroundColor;
if(_backgroundColor == null) {
_backgroundColor = Colors.white;
}
return CustomPaint(
size: MediaQuery.of(context).size,
painter: _GradientLinearProgressPainter(
strokeWidth: strokeWidth,
value: value,
colors: _colors,
backgroundColor: _backgroundColor,
soldNumString: soldNumString),
);
}
}
class _GradientLinearProgressPainter extends CustomPainter{
final double strokeWidth;
final double value;
final List<Color>colors;
final mPaint = Paint();
final Color backgroundColor;
final String soldNumString;
_GradientLinearProgressPainter(
{this.strokeWidth = 2.0,
@required this.colors,
this.value = 0.0,
this.backgroundColor,
this.soldNumString}) {
mPaint.strokeCap = StrokeCap.round;
mPaint.style = PaintingStyle.fill;
mPaint.isAntiAlias = true;
mPaint.strokeWidth = strokeWidth;
mPaint.color = backgroundColor;
}
@override
void paint(Canvas canvas, Size size) {
double _offset = strokeWidth / 2; //留一定的偏移量
var start = Offset(_offset, _offset); //画笔起点坐标
var valueEnd =
Offset(1 *(size.width - 2 * _offset)+ _offset, _offset); //计算进度的长度
if(value > 0) {
canvas.saveLayer(Offset.zero& size, Paint());
/// 绘制背景
Rect rect = Rect.fromPoints(start, valueEnd);
canvas.drawLine(start, valueEnd, mPaint);
mPaint.blendMode = BlendMode.srcIn;
/// 绘制进度
mPaint.strokeCap = StrokeCap.square;
mPaint.shader = LinearGradient(colors: colors).createShader(rect);
valueEnd = valueEnd = Offset(
value *(size.width - 2 * _offset)+ _offset, _offset); //计算进度的长度
canvas.drawLine(start, valueEnd, mPaint);
canvas.restore();
}else{
canvas.drawLine(start, valueEnd, mPaint);
}
double marginStart = 0;
if(value >= 0.85) {
marginStart = 22.5;
}else{
marginStart = 8;
}
/// 绘制反色文字
double fontSize = 10;
double marginTop =(strokeWidth - fontSize)/ 2.0;
start = Offset(_offset, 0); //画笔起点坐标
valueEnd = Offset(value *(size.width - 2 * _offset)+ _offset * 2,
_offset * 2); //计算进度的长度
var textPainter = TextPainter(
text: TextSpan(
text: soldNumString,
style: TextStyle(color: Color(0xffFC5E82), fontSize: fontSize)),
textDirection: TextDirection.ltr,
maxLines: 1,
)..layout();
textPainter.paint(canvas, Offset(marginStart, marginTop));
if(value > 0) {
canvas.saveLayer(Rect.fromPoints(start, valueEnd), Paint());
var textPainter2 = TextPainter(
text: TextSpan(
text: soldNumString,
style: TextStyle(color: ColorCons.white, fontSize: fontSize)),
textDirection: TextDirection.ltr,
maxLines: 1,
)..layout();
textPainter2.paint(canvas, Offset(marginStart, marginTop));
textPainter2.paint(canvas, Offset(marginStart, marginTop));
canvas.restore();
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate)=> true;
}
```
Flutter Xfermode 实现
13 mins.
5281
7
评论区