1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import '../../gallery/demo.dart';
class ProgressIndicatorDemo extends StatefulWidget {
static const String routeName = '/material/progress-indicator';
@override
_ProgressIndicatorDemoState createState() => _ProgressIndicatorDemoState();
}
class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> with SingleTickerProviderStateMixin {
AnimationController _controller;
Animation<double> _animation;
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(milliseconds: 1500),
vsync: this,
animationBehavior: AnimationBehavior.preserve,
)..forward();
_animation = CurvedAnimation(
parent: _controller,
curve: const Interval(0.0, 0.9, curve: Curves.fastOutSlowIn),
reverseCurve: Curves.fastOutSlowIn,
)..addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.dismissed)
_controller.forward();
else if (status == AnimationStatus.completed)
_controller.reverse();
});
}
@override
void dispose() {
_controller.stop();
super.dispose();
}
void _handleTap() {
setState(() {
// valueAnimation.isAnimating is part of our build state
if (_controller.isAnimating) {
_controller.stop();
} else {
switch (_controller.status) {
case AnimationStatus.dismissed:
case AnimationStatus.forward:
_controller.forward();
break;
case AnimationStatus.reverse:
case AnimationStatus.completed:
_controller.reverse();
break;
}
}
});
}
Widget _buildIndicators(BuildContext context, Widget child) {
final List<Widget> indicators = <Widget>[
const SizedBox(
width: 200.0,
child: LinearProgressIndicator(),
),
const LinearProgressIndicator(),
const LinearProgressIndicator(),
LinearProgressIndicator(value: _animation.value),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
const CircularProgressIndicator(),
SizedBox(
width: 20.0,
height: 20.0,
child: CircularProgressIndicator(value: _animation.value),
),
SizedBox(
width: 100.0,
height: 20.0,
child: Text('${(_animation.value * 100.0).toStringAsFixed(1)}%',
textAlign: TextAlign.right,
),
),
],
),
];
return Column(
children: indicators
.map<Widget>((Widget c) => Container(child: c, margin: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 20.0)))
.toList(),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Progress indicators'),
actions: <Widget>[MaterialDemoDocumentationButton(ProgressIndicatorDemo.routeName)],
),
body: Center(
child: SingleChildScrollView(
child: DefaultTextStyle(
style: Theme.of(context).textTheme.title,
child: GestureDetector(
onTap: _handleTap,
behavior: HitTestBehavior.opaque,
child: SafeArea(
top: false,
bottom: false,
child: Container(
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 8.0),
child: AnimatedBuilder(
animation: _animation,
builder: _buildIndicators,
),
),
),
),
),
),
),
);
}
}