Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix BrnProgressChart 设置颜色,背景色,以及动画无效 #322

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ class ProgressChartExampleState extends State<ProgressChartExample> {
height: 44,
),
BrnProgressChart(
key: UniqueKey(),
width: 200,
width: 300,
height: 20,
value: count,
duration: Duration(milliseconds: 500),
colors: [Colors.lightBlueAccent, Colors.blue],
backgroundColor: Colors.grey,
showAnimation: true,
isReverse: true,
brnProgressIndicatorBuilder: (BuildContext context, double value) {
return Text(
'自定义文本:$value',
'自定义:$value',
style: TextStyle(color: Colors.white),
);
},
Expand Down
130 changes: 102 additions & 28 deletions lib/src/components/charts/brn_progress_chart/brn_progress_chart.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@


import 'package:bruno/src/components/charts/brn_progress_chart/brn_progress_chart_painter.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

/// 在进度条上展示的 Widget
Expand Down Expand Up @@ -36,6 +37,12 @@ class BrnProgressChart extends StatefulWidget {
/// 是否展示动画,默认 false
final bool showAnimation;

/// 动画时长,默认 Duration(milliseconds: 250)
final Duration duration;

/// 进度条是否从上次的值开始
final bool isReverse;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isReverse 字面意思和注释说明的作用不同。

是想表达进度条动画从最近一次的值开始不. : )

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isAnimationStartFromLastValue 这样命名呢😂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对,是这个意思,我改下命名


const BrnProgressChart(
{Key? key,
this.width = 0,
Expand All @@ -46,7 +53,9 @@ class BrnProgressChart extends StatefulWidget {
this.brnProgressIndicatorBuilder,
this.colors = const [Colors.blueAccent, Colors.blue],
this.backgroundColor = Colors.lightBlueAccent,
this.showAnimation = false})
this.showAnimation = false,
this.isReverse = false,
this.duration = const Duration(milliseconds: 250),})
: assert(0 <= value && value <= 1, 'value 必须在 0 到 1 之间'),
super(key: key);

Expand All @@ -59,59 +68,124 @@ class BrnProgressChart extends StatefulWidget {
class BrnProgressChartState extends State<BrnProgressChart>
with SingleTickerProviderStateMixin {
late Animation<double> _animation;
AnimationController? _animationController;
double _value = 0;
late AnimationController _animationController =
AnimationController(vsync: this);
double _lastValue = 0;

bool get _isAnimation => widget.showAnimation;

void _initAnimation() {
final double begin = widget.isReverse ? _lastValue : 0;
final double end = widget.value;
final Tween<double> tween = Tween<double>(begin: begin, end: end);
_animationController.duration =
_isAnimation ? widget.duration : Duration.zero;
_animation = tween.animate(_animationController);
_animationController.reset();
_animationController.forward();
_lastValue = end;
}

@override
void initState() {
super.initState();
if (widget.showAnimation) {
_animationController = AnimationController(
vsync: this, duration: Duration(milliseconds: 250));
Tween tween = Tween<double>(begin: 0, end: widget.value);
_animation = tween.animate(_animationController!) as Animation<double>;
_animation.addListener(() {
setState(() {
_value = _animation.value;
});
});
_animationController!.forward();
} else {
_value = widget.value;
_initAnimation();
}

@override
void didUpdateWidget(covariant BrnProgressChart oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.value != widget.value) {
if (_animationController.isAnimating == true) {
_animationController.stop();
}
_initAnimation();
}
}

@override
void dispose() {
_animationController?.dispose();
_animationController.dispose();
super.dispose();
}

Widget _indicatorWidgetBuilder(BuildContext context, double value) {
return Text(
'$value',
style: widget.textStyle,
);
}

@override
Widget build(BuildContext context) {
final double _value = widget.value;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_value 临时变量是不是可以去掉 : )

return Stack(
children: <Widget>[
CustomPaint(
size: Size(widget.width, widget.height),
painter: BrnProgressChartPainter(value: _value),
painter: BrnProgressChartPainter(
value: _value,
animation: _animation,
backgroundColor: widget.backgroundColor,
colors: widget.colors,
),
),
Container(
width: widget.width,
height: widget.height,
padding: EdgeInsets.only(left: widget.indicatorLeftPadding),
alignment: Alignment.centerLeft,
child: null != widget.brnProgressIndicatorBuilder
? widget.brnProgressIndicatorBuilder!(context, _value)
: _indicatorWidgetBuilder(context, _value),
child: IndicatorWidgetBuilder(
notifier: _animation,
value: _value,
textStyle: widget.textStyle,
brnProgressIndicatorBuilder: widget.brnProgressIndicatorBuilder,
),
)
],
);
}
}

class IndicatorWidgetBuilder extends StatefulWidget {
const IndicatorWidgetBuilder({
Key? key,
required this.value,
required this.textStyle,
this.notifier,
this.brnProgressIndicatorBuilder,
}) : super(key: key);

final ValueListenable<double>? notifier;
final double value;
final TextStyle textStyle;
final BrnProgressIndicatorBuilder? brnProgressIndicatorBuilder;

@override
State<IndicatorWidgetBuilder> createState() => _IndicatorWidgetBuilderState();
}

class _IndicatorWidgetBuilderState extends State<IndicatorWidgetBuilder> {
late double _value;

void _changeListener() {
final double value = widget.notifier?.value ?? widget.value;
setState(() {
_value = value;
});
}

@override
void initState() {
super.initState();
_value = widget.value;
widget.notifier?.addListener(_changeListener);
}

@override
void dispose() {
widget.notifier?.removeListener(_changeListener);
super.dispose();
}

@override
Widget build(BuildContext context) {
final BrnProgressIndicatorBuilder? builder =
widget.brnProgressIndicatorBuilder;
return builder?.call(context, _value) ??
Text('文本:$_value', style: widget.textStyle);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ class BrnProgressChartPainter extends CustomPainter {
/// 进度值
final double value;

/// 动画
final Animation<double>? animation;

/// 背景色
final Color backgroundColor;

Expand All @@ -20,13 +23,18 @@ class BrnProgressChartPainter extends CustomPainter {

BrnProgressChartPainter(
{this.value = 0.2,
this.animation,
this.colors = const [Color(0xFF1545FD), Color(0xFF0984F9)],
this.backgroundColor = const Color(0x7A90C9FF),
this.radius = 4,
this.alwaysShowRadius = true});
this.alwaysShowRadius = true})
: super(repaint: animation){
assert(colors.isNotEmpty, 'colors must not be empty');
}

@override
void paint(Canvas canvas, Size size) {
final double value = animation?.value ?? this.value;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

局部变量 value 作用域覆盖了 类的字段 value

可能会对 45、46 行的 value 判断有影响

Paint backgroundPaint = Paint()
..color = this.backgroundColor
..style = PaintingStyle.fill;
Expand All @@ -48,22 +56,24 @@ class BrnProgressChartPainter extends CustomPainter {
1 == value && false == this.alwaysShowRadius ? 0 : this.radius),
topRight: Radius.circular(
1 == value && false == this.alwaysShowRadius ? 0 : this.radius));

Shader progressBarShader = LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
tileMode: TileMode.clamp,
colors: (this.colors.length > 1)
? this.colors
: [this.colors[0], this.colors[0]])
.createShader(progressBarRect);
Paint progressBarPaint = Paint()..shader = progressBarShader;
final bool isNotSingleColor = colors.length > 1;
Paint progressBarPaint = Paint();
if (isNotSingleColor) {
progressBarPaint.shader = LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
tileMode: TileMode.clamp,
colors: colors)
.createShader(progressBarRect);
} else {
progressBarPaint.color = colors[0];
}

canvas.drawRRect(progressBarRRect, progressBarPaint);
}

@override
bool shouldRepaint(BrnProgressChartPainter oldDelegate) {
return this.value != oldDelegate.value;
return false;
}
}