初始化

This commit is contained in:
谢宇宁
2026-09-15 15:44:13 +07:00
commit a23ba685e9
1065 changed files with 101122 additions and 0 deletions
@@ -0,0 +1,73 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
//TabBar 自定义指示器:底部一小条,支持纯色/渐变、自定义圆角与离底距离
class CustomIndicator extends Decoration {
final double width; //指示器宽度
final double height; //指示器高度
final Color color; //纯色时的颜色
final bool isGradient; //是否渐变
final List<Color> gradientColors; //渐变色,isGradient 为 true 才生效
final double offsetY; //在贴底的基础上再往上移多少
final BorderRadius? borderRadius; //圆角,不传默认 1
const CustomIndicator({
this.width = 16.0,
this.height = 3.0,
this.color = const Color(0xffF68804),
this.gradientColors = const [Color(0x00F68804), Color(0xffF68804)],
this.isGradient = false,
this.offsetY = 0,
this.borderRadius,
});
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) => _IndicatorPainter(this, onChanged);
//必须实现值相等:TabBar 用 indicator != oldWidget.indicator 决定要不要重建 painter
//(tabs.dart didUpdateWidget / _IndicatorPainter.shouldRepaint)。调用方都是在 build 里内联
//new 出来的,只按引用比较的话每次 rebuild 都判不等 → 白重建画笔、白重绘一次
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
return other is CustomIndicator &&
other.width == width &&
other.height == height &&
other.color == color &&
other.isGradient == isGradient &&
other.offsetY == offsetY &&
other.borderRadius == borderRadius &&
listEquals(other.gradientColors, gradientColors);
}
@override
int get hashCode => Object.hash(width, height, color, isGradient, offsetY, borderRadius, Object.hashAll(gradientColors));
}
class _IndicatorPainter extends BoxPainter {
final CustomIndicator deco;
_IndicatorPainter(this.deco, super.onChanged);
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
assert(configuration.size != null);
final size = configuration.size!;
//横向居中,纵向贴底再上移 offsetY
final topLeft = Offset(
offset.dx + (size.width - deco.width) / 2,
size.height - deco.height - deco.offsetY,
);
final rect = topLeft & Size(deco.width, deco.height);
final paint = Paint();
if (deco.isGradient) {
paint.shader = LinearGradient(colors: deco.gradientColors).createShader(rect);
} else {
paint.color = deco.color;
}
final borderRadius = deco.borderRadius ?? const BorderRadius.all(Radius.circular(1));
canvas.drawRRect(borderRadius.toRRect(rect), paint);
}
}