Skip to content

Commit 4269db5

Browse files
committed
增加手势功能
1 parent c9cfd13 commit 4269db5

2 files changed

Lines changed: 153 additions & 28 deletions

File tree

progress/lib/main.dart

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Home extends StatefulWidget {
2828
}
2929

3030
class _HomeState extends State<Home> {
31+
TextLabel buttonLabel = const TextLabel("50%");
3132
@override
3233
Widget build(BuildContext context) {
3334
return Scaffold(
@@ -64,8 +65,30 @@ class _HomeState extends State<Home> {
6465
),
6566
]),
6667
_buildSection("微型进度条", [
67-
Progress.micro(value: 0.3, label: const IconLabel(TDIcons.arrow_down)),
68+
Progress.micro(value: 0.3),
6869
]),
70+
_buildSection("微型按钮进度条", [
71+
Row(
72+
children: [
73+
Progress.micro(value: 0.3, onTap: (){}, label: const IconLabel(Icons.play_arrow, color: Colors.blue)),
74+
const SizedBox(width: 10),
75+
Progress.micro(value: 0.3, onTap: (){}, label: const IconLabel(Icons.pause, color: Colors.blue)),
76+
const SizedBox(width: 10),
77+
Progress.micro(value: 0.3, onTap: (){}, label: const IconLabel(Icons.stop, color: Colors.blue))
78+
]
79+
)
80+
]),
81+
_buildSection("按钮进度条", [
82+
Progress.button(
83+
onTap: (){
84+
setState(() {
85+
buttonLabel = buttonLabel.data == "50%" ? const TextLabel("继续") : const TextLabel("50%");
86+
});
87+
},
88+
value: .5,
89+
label: buttonLabel,
90+
),
91+
])
6992
],
7093
),
7194
);

progress/lib/progress.dart

Lines changed: 129 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:tdesign_flutter/tdesign_flutter.dart';
33

44
// 用于区分线性和圆形进度条的枚举
5-
enum _ProgressType { linear, circular, micro }
5+
enum _ProgressType { linear, circular, micro, button }
66

77
//label位置的枚举
88
enum ProgressLabelPosition { inside, left, right }
@@ -93,20 +93,56 @@ class Progress {
9393
Color? color,
9494
Color backgroundColor = const Color(0xFFEEEEEE),
9595
double circleRadius = 20.0,
96-
bool showLabel = false}) {
96+
VoidCallback? onTap,
97+
VoidCallback? onLongPress,
98+
bool showLabel = true}) {
9799
return _ProgressIndicator(
98100
key: key,
99101
value: value,
100-
label: label,
102+
label: label ?? const TextLabel(""),
101103
progressStatus: progressStatus,
102104
strokeWidth: strokeWidth,
103105
color: color,
104106
backgroundColor: backgroundColor,
105107
circleRadius: circleRadius,
108+
onTap: onTap,
109+
onLongPress: onLongPress,
106110
showLabel: showLabel,
107111
type: _ProgressType.micro,
108112
);
109113
}
114+
115+
// 构建按钮进度条
116+
static Widget button<T extends LabelWidget>(
117+
{Key? key,
118+
double? value,
119+
T? label,
120+
ProgressStatus progressStatus = ProgressStatus.primary,
121+
ProgressLabelPosition progressLabelPosition =
122+
ProgressLabelPosition.inside,
123+
double strokeWidth = 60.0,
124+
Color? color,
125+
Color backgroundColor = Colors.blue,
126+
BorderRadiusGeometry borderRadius =
127+
const BorderRadius.all(Radius.circular(10)),
128+
VoidCallback? onTap,
129+
VoidCallback? onLongPress,
130+
bool showLabel = true}) {
131+
return _ProgressIndicator<T>(
132+
key: key,
133+
value: value,
134+
label: label,
135+
progressStatus: progressStatus,
136+
progressLabelPosition: progressLabelPosition,
137+
strokeWidth: strokeWidth,
138+
color: color,
139+
backgroundColor: backgroundColor,
140+
borderRadius: borderRadius,
141+
showLabel: showLabel,
142+
onTap: onTap,
143+
onLongPress: onLongPress,
144+
type: _ProgressType.button);
145+
}
110146
}
111147

112148
// 构建进度条基础小部件类
@@ -123,6 +159,8 @@ class _ProgressIndicator<T extends LabelWidget> extends StatefulWidget {
123159
final StrokeCap strokeCap;
124160
final ProgressStatus progressStatus;
125161
final bool showLabel;
162+
final VoidCallback? onTap;
163+
final VoidCallback? onLongPress;
126164

127165
const _ProgressIndicator(
128166
{Key? key,
@@ -137,7 +175,9 @@ class _ProgressIndicator<T extends LabelWidget> extends StatefulWidget {
137175
this.type = _ProgressType.linear,
138176
this.strokeCap = StrokeCap.round,
139177
this.progressStatus = ProgressStatus.primary,
140-
this.showLabel = true})
178+
this.showLabel = true,
179+
this.onTap,
180+
this.onLongPress})
141181
: super(key: key);
142182

143183
@override
@@ -261,7 +301,9 @@ class _ProgressIndicatorState<T extends LabelWidget>
261301
else if (widget.type == _ProgressType.circular)
262302
_buildCircularProgress()
263303
else if (widget.type == _ProgressType.micro)
264-
_buildMicroProgress(),
304+
_buildMicroProgress()
305+
else if (widget.type == _ProgressType.button)
306+
_buildButtonProgress()
265307
],
266308
);
267309
}
@@ -305,7 +347,7 @@ class _ProgressIndicatorState<T extends LabelWidget>
305347
Widget _buildOutsideLabel() {
306348
return AnimatedBuilder(
307349
animation: _animation,
308-
builder: (context, child) {
350+
builder: (context, child) {
309351
return Row(
310352
crossAxisAlignment: CrossAxisAlignment.center,
311353
children: [
@@ -406,10 +448,15 @@ class _ProgressIndicatorState<T extends LabelWidget>
406448
fontWeight = FontWeight.bold;
407449
break;
408450
case _ProgressType.micro:
409-
iconSize = widget.circleRadius * 0.4;
451+
iconSize = widget.circleRadius * 0.6;
410452
fontSize = widget.circleRadius * 0.2;
411453
fontWeight = FontWeight.normal;
412454
break;
455+
case _ProgressType.button:
456+
iconSize = widget.strokeWidth * 0.8;
457+
fontSize = widget.strokeWidth * 0.4;
458+
fontWeight = FontWeight.normal;
459+
break;
413460
default:
414461
iconSize = 20;
415462
fontSize = 12;
@@ -464,26 +511,81 @@ class _ProgressIndicatorState<T extends LabelWidget>
464511
return AnimatedBuilder(
465512
animation: _animation,
466513
builder: (context, child) {
467-
return Stack(
468-
alignment: Alignment.center,
469-
children: [
470-
SizedBox(
471-
height: widget.circleRadius,
472-
width: widget.circleRadius,
473-
child: Padding(
474-
padding: EdgeInsets.all(widget.strokeWidth / 2),
475-
child: CircularProgressIndicator(
476-
value: widget.value != null ? _animation.value : null,
477-
backgroundColor: widget.backgroundColor,
478-
strokeCap: widget.strokeCap,
479-
valueColor: AlwaysStoppedAnimation<Color>(_effectiveColor),
480-
strokeWidth: widget.strokeWidth,
481-
),
482-
),
483-
),
484-
if (widget.showLabel) _buildLabelWidget(Colors.black),
485-
],
514+
return GestureDetector(
515+
onTap: widget.onTap,
516+
onLongPress: widget.onLongPress,
517+
child: Stack(
518+
alignment: Alignment.center,
519+
children: [
520+
_buildMicroOutline(),
521+
if (widget.showLabel) _buildLabelWidget(Colors.black),
522+
],
523+
)
486524
);
487-
});
525+
}
526+
);
527+
}
528+
529+
Widget _buildMicroOutline() {
530+
return SizedBox(
531+
height: widget.circleRadius,
532+
width: widget.circleRadius,
533+
child: Padding(
534+
padding: EdgeInsets.all(widget.strokeWidth / 2),
535+
child: CircularProgressIndicator(
536+
value: widget.value != null ? _animation.value : null,
537+
backgroundColor: widget.backgroundColor,
538+
strokeCap: widget.strokeCap,
539+
valueColor: AlwaysStoppedAnimation<Color>(_effectiveColor),
540+
strokeWidth: widget.strokeWidth,
541+
),
542+
),
543+
);
544+
}
545+
546+
Widget _buildButtonProgress() {
547+
return LayoutBuilder(
548+
builder: (context, constraints) {
549+
final maxWidth = constraints.maxWidth;
550+
return AnimatedBuilder(
551+
animation: _animation,
552+
builder: (context, child) {
553+
final progressWidth = maxWidth * _animation.value;
554+
return GestureDetector(
555+
onTap: widget.onTap,
556+
onLongPress: widget.onLongPress,
557+
child: Stack(
558+
children: [
559+
_buildBackgroundContainer(),
560+
_buildButtonActiveContainer(progressWidth),
561+
if (widget.showLabel) _buildButtonLabel(maxWidth),
562+
],
563+
)
564+
);
565+
}
566+
);
567+
},
568+
);
569+
}
570+
571+
// 按钮进度条内容器
572+
Widget _buildButtonActiveContainer(double progressWidth) {
573+
return Container(
574+
height: widget.strokeWidth,
575+
width: progressWidth,
576+
decoration: BoxDecoration(
577+
gradient: LinearGradient(
578+
colors: [widget.backgroundColor, Colors.white.withOpacity(.2)]),
579+
borderRadius: widget.borderRadius,
580+
),
581+
);
582+
}
583+
584+
Widget _buildButtonLabel(double maxWidth) {
585+
return Container(
586+
height: widget.strokeWidth,
587+
alignment: Alignment.center,
588+
child: _buildLabelWidget(Colors.white),
589+
);
488590
}
489591
}

0 commit comments

Comments
 (0)