progress_indicator_demo.dart 3.84 KB
Newer Older
1 2 3 4
// 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.

5
import 'package:flutter/material.dart';
6

7 8
import '../../gallery/demo.dart';

9
class ProgressIndicatorDemo extends StatefulWidget {
10
  static const String routeName = '/material/progress-indicator';
11

12
  @override
13
  _ProgressIndicatorDemoState createState() => _ProgressIndicatorDemoState();
14
}
15

16
class _ProgressIndicatorDemoState extends State<ProgressIndicatorDemo> with SingleTickerProviderStateMixin {
17 18
  AnimationController _controller;
  Animation<double> _animation;
19

20
  @override
21 22
  void initState() {
    super.initState();
23
    _controller = AnimationController(
24 25
      duration: const Duration(milliseconds: 1500),
      vsync: this,
26
      animationBehavior: AnimationBehavior.preserve,
Adam Barth's avatar
Adam Barth committed
27
    )..forward();
28

29
    _animation = CurvedAnimation(
30
      parent: _controller,
31
      curve: const Interval(0.0, 0.9, curve: Curves.fastOutSlowIn),
32
      reverseCurve: Curves.fastOutSlowIn,
33
    )..addStatusListener((AnimationStatus status) {
Adam Barth's avatar
Adam Barth committed
34
      if (status == AnimationStatus.dismissed)
35
        _controller.forward();
Adam Barth's avatar
Adam Barth committed
36
      else if (status == AnimationStatus.completed)
37
        _controller.reverse();
38
    });
39 40
  }

41 42 43 44 45
  @override
  void dispose() {
    _controller.stop();
    super.dispose();
  }
46

Adam Barth's avatar
Adam Barth committed
47
  void _handleTap() {
48 49
    setState(() {
      // valueAnimation.isAnimating is part of our build state
50 51
      if (_controller.isAnimating) {
        _controller.stop();
Adam Barth's avatar
Adam Barth committed
52
      } else {
53
        switch (_controller.status) {
Adam Barth's avatar
Adam Barth committed
54 55
          case AnimationStatus.dismissed:
          case AnimationStatus.forward:
56
            _controller.forward();
Adam Barth's avatar
Adam Barth committed
57 58 59
            break;
          case AnimationStatus.reverse:
          case AnimationStatus.completed:
60
            _controller.reverse();
Adam Barth's avatar
Adam Barth committed
61 62 63
            break;
        }
      }
64
    });
65 66
  }

Adam Barth's avatar
Adam Barth committed
67
  Widget _buildIndicators(BuildContext context, Widget child) {
68
    final List<Widget> indicators = <Widget>[
69
      const SizedBox(
70
        width: 200.0,
71
        child: LinearProgressIndicator(),
72
      ),
73 74
      const LinearProgressIndicator(),
      const LinearProgressIndicator(),
75 76
      LinearProgressIndicator(value: _animation.value),
      Row(
77 78
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
79
          const CircularProgressIndicator(),
80
          SizedBox(
81 82
              width: 20.0,
              height: 20.0,
83
              child: CircularProgressIndicator(value: _animation.value),
84
          ),
85
          SizedBox(
86
            width: 100.0,
87
            height: 20.0,
88
            child: Text('${(_animation.value * 100.0).toStringAsFixed(1)}%',
89
              textAlign: TextAlign.right,
90 91 92 93
            ),
          ),
        ],
      ),
94
    ];
95
    return Column(
96
      children: indicators
97
        .map<Widget>((Widget c) => Container(child: c, margin: const EdgeInsets.symmetric(vertical: 15.0, horizontal: 20.0)))
98 99 100 101
        .toList(),
    );
  }

102
  @override
103
  Widget build(BuildContext context) {
104
    return Scaffold(
105 106 107 108
      appBar: AppBar(
        title: const Text('Progress indicators'),
        actions: <Widget>[MaterialDemoDocumentationButton(ProgressIndicatorDemo.routeName)],
      ),
109 110 111
      body: Center(
        child: SingleChildScrollView(
          child: DefaultTextStyle(
112
            style: Theme.of(context).textTheme.title,
113
            child: GestureDetector(
114 115
              onTap: _handleTap,
              behavior: HitTestBehavior.opaque,
116
              child: SafeArea(
117 118
                top: false,
                bottom: false,
119
                child: Container(
120
                  padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 8.0),
121
                  child: AnimatedBuilder(
122
                    animation: _animation,
123
                    builder: _buildIndicators,
124 125 126 127 128 129 130
                  ),
                ),
              ),
            ),
          ),
        ),
      ),
131 132 133
    );
  }
}