<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 實例:圓形漸變進度條(自繪) 本節我們實現一個圓形漸變進度條,它支持: 1. 支持多種漸變色。 2. 任意弧度;整個進度可以不是整圓。 3. 可以自定義粗細、兩端是否圓角等樣式。 可以發現要實現這樣的一個進度條是無法通過現有組件組合而成的,所以我們通過自繪方式實現。 實現代碼如下: ``` import 'dart:math'; import 'package:flutter/material.dart'; class GradientCircularProgressIndicator extends StatelessWidget { GradientCircularProgressIndicator({ this.stokeWidth = 2.0, @required this.radius, @required this.colors, this.stops, this.strokeCapRound = false, this.backgroundColor = const Color(0xFFEEEEEE), this.totalAngle = 2 * pi, this.value }); ///粗細 final double stokeWidth; /// 圓的半徑 final double radius; ///兩端是否為圓角 final bool strokeCapRound; /// 當前進度,取值范圍 [0.0-1.0] final double value; /// 進度條背景色 final Color backgroundColor; /// 進度條的總弧度,2*PI為整圓,小于2*PI則不是整圓 final double totalAngle; /// 漸變色數組 final List<Color> colors; /// 漸變色的終止點,對應colors屬性 final List<double> stops; @override Widget build(BuildContext context) { double _offset = .0; // 如果兩端為圓角,則需要對起始位置進行調整,否則圓角部分會偏離起始位置 // 下面調整的角度的計算公式是通過數學幾何知識得出,讀者有興趣可以研究一下為什么是這樣 if (strokeCapRound) { _offset = asin(stokeWidth / (radius * 2 - stokeWidth)); } var _colors = colors; if (_colors == null) { Color color = Theme .of(context) .accentColor; _colors = [color, color]; } return Transform.rotate( angle: -pi / 2.0 - _offset, child: CustomPaint( size: Size.fromRadius(radius), painter: _GradientCircularProgressPainter( stokeWidth: stokeWidth, strokeCapRound: strokeCapRound, backgroundColor: backgroundColor, value: value, total: totalAngle, radius: radius, colors: _colors, ) ), ); } } //實現畫筆 class _GradientCircularProgressPainter extends CustomPainter { _GradientCircularProgressPainter({ this.stokeWidth: 10.0, this.strokeCapRound: false, this.backgroundColor = const Color(0xFFEEEEEE), this.radius, this.total = 2 * pi, @required this.colors, this.stops, this.value }); final double stokeWidth; final bool strokeCapRound; final double value; final Color backgroundColor; final List<Color> colors; final double total; final double radius; final List<double> stops; @override void paint(Canvas canvas, Size size) { if (radius != null) { size = Size.fromRadius(radius); } double _offset = stokeWidth / 2.0; double _value = (value ?? .0); _value = _value.clamp(.0, 1.0) * total; double _start = .0; if (strokeCapRound) { _start = asin(stokeWidth/ (size.width - stokeWidth)); } Rect rect = Offset(_offset, _offset) & Size( size.width - stokeWidth, size.height - stokeWidth ); var paint = Paint() ..strokeCap = strokeCapRound ? StrokeCap.round : StrokeCap.butt ..style = PaintingStyle.stroke ..isAntiAlias = true ..strokeWidth = stokeWidth; // 先畫背景 if (backgroundColor != Colors.transparent) { paint.color = backgroundColor; canvas.drawArc( rect, _start, total, false, paint ); } // 再畫前景,應用漸變 if (_value > 0) { paint.shader = SweepGradient( startAngle: 0.0, endAngle: _value, colors: colors, stops: stops, ).createShader(rect); canvas.drawArc( rect, _start, _value, false, paint ); } } @override bool shouldRepaint(CustomPainter oldDelegate) => true; } ``` 下面我們來測試一下,為了盡可能多的展示GradientCircularProgressIndicator的不同外觀和用途,這個示例代碼會比較長,并且添加了動畫,建議讀者將此示例運行起來觀看實際效果,我們先看看其中的一幀動畫的截圖: ![](https://box.kancloud.cn/4cea87cbe9c575e51882195216b7afb9_326x502.png) 完整的代碼: ``` import 'dart:math'; import 'package:flutter/material.dart'; import '../widgets/index.dart'; class GradientCircularProgressRoute extends StatefulWidget { @override GradientCircularProgressRouteState createState() { return new GradientCircularProgressRouteState(); } } class GradientCircularProgressRouteState extends State<GradientCircularProgressRoute> with TickerProviderStateMixin { AnimationController _animationController; @override void initState() { super.initState(); _animationController = new AnimationController(vsync: this, duration: Duration(seconds: 3)); bool isForward = true; _animationController.addStatusListener((status) { if (status == AnimationStatus.forward) { isForward = true; } else if (status == AnimationStatus.completed || status == AnimationStatus.dismissed) { if (isForward) { _animationController.reverse(); } else { _animationController.forward(); } } else if (status == AnimationStatus.reverse) { isForward = false; } }); _animationController.forward(); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return SingleChildScrollView( child: Center( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ AnimatedBuilder( animation: _animationController, builder: (BuildContext context, Widget child) { return Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Column( children: <Widget>[ Wrap( spacing: 10.0, runSpacing: 16.0, children: <Widget>[ GradientCircularProgressIndicator( // No gradient colors: [Colors.blue, Colors.blue], radius: 50.0, stokeWidth: 3.0, value: _animationController.value, ), GradientCircularProgressIndicator( colors: [Colors.red, Colors.orange], radius: 50.0, stokeWidth: 3.0, value: _animationController.value, ), GradientCircularProgressIndicator( colors: [Colors.red, Colors.orange, Colors.red], radius: 50.0, stokeWidth: 5.0, value: _animationController.value, ), GradientCircularProgressIndicator( colors: [Colors.teal, Colors.cyan], radius: 50.0, stokeWidth: 5.0, strokeCapRound: true, value: CurvedAnimation( parent: _animationController, curve: Curves.decelerate) .value, ), TurnBox( turns: 1 / 8, child: GradientCircularProgressIndicator( colors: [Colors.red, Colors.orange, Colors.red], radius: 50.0, stokeWidth: 5.0, strokeCapRound: true, backgroundColor: Colors.red[50], totalAngle: 1.5 * pi, value: CurvedAnimation( parent: _animationController, curve: Curves.ease) .value), ), RotatedBox( quarterTurns: 1, child: GradientCircularProgressIndicator( colors: [Colors.blue[700], Colors.blue[200]], radius: 50.0, stokeWidth: 3.0, strokeCapRound: true, backgroundColor: Colors.transparent, value: _animationController.value), ), GradientCircularProgressIndicator( colors: [ Colors.red, Colors.amber, Colors.cyan, Colors.green[200], Colors.blue, Colors.red ], radius: 50.0, stokeWidth: 5.0, strokeCapRound: true, value: _animationController.value, ), ], ), GradientCircularProgressIndicator( colors: [Colors.blue[700], Colors.blue[200]], radius: 100.0, stokeWidth: 20.0, value: _animationController.value, ), Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: GradientCircularProgressIndicator( colors: [Colors.blue[700], Colors.blue[300]], radius: 100.0, stokeWidth: 20.0, value: _animationController.value, strokeCapRound: true, ), ), //剪裁半圓 ClipRect( child: Align( alignment: Alignment.topCenter, heightFactor: .5, child: Padding( padding: const EdgeInsets.only(bottom: 8.0), child: SizedBox( //width: 100.0, child: TurnBox( turns: .75, child: GradientCircularProgressIndicator( colors: [Colors.teal, Colors.cyan[500]], radius: 100.0, stokeWidth: 8.0, value: _animationController.value, totalAngle: pi, strokeCapRound: true, ), ), ), ), ), ), SizedBox( height: 104.0, width: 200.0, child: Stack( alignment: Alignment.center, children: <Widget>[ Positioned( height: 200.0, top: .0, child: TurnBox( turns: .75, child: GradientCircularProgressIndicator( colors: [Colors.teal, Colors.cyan[500]], radius: 100.0, stokeWidth: 8.0, value: _animationController.value, totalAngle: pi, strokeCapRound: true, ), ), ), Padding( padding: const EdgeInsets.only(top: 10.0), child: Text( "${(_animationController.value * 100).toInt()}%", style: TextStyle( fontSize: 25.0, color: Colors.blueGrey, ), ), ) ], ), ), ], ), ); }, ), ], ), ), ); } } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看