您好,登錄后才能下訂單哦!
今天小編給大家分享一下Flutter投票組件如何使用的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
開發(fā)遇到的問(wèn)題
1.選項(xiàng)列表的高度,自適應(yīng)的問(wèn)題;
2.進(jìn)度條動(dòng)畫的問(wèn)題;
3.列表回收機(jī)制,導(dǎo)致進(jìn)度條動(dòng)畫重復(fù);
4.自定義進(jìn)度條四周圓角;
如何解決問(wèn)題
拿到數(shù)組列表最長(zhǎng)的數(shù)據(jù),然后根據(jù)屏幕寬度計(jì)算,超出一行則設(shè)定兩行高度,否則使用一行的高度;
_didExceedOneMoreLines(String text, double width, TextStyle style) { final span = TextSpan(text: text, style: style); final tp = TextPainter(text: span, maxLines: 1, textDirection: TextDirection.ltr); tp.layout(maxWidth: width); if (tp.didExceedMaxLines) { //設(shè)置item選項(xiàng)的高度 _itemHeight = 100.w; } }
Widget控件初始化(initState)方法時(shí),使用AnimationController動(dòng)畫,并實(shí)現(xiàn)SingleTickerProviderStateMixin,在build方法當(dāng)中調(diào)用 _controller.animateTo()
AnimationController _controller; _controller = AnimationController( vsync: this, duration: const Duration(seconds: 1), )..addListener(() { setState(() {}); }); //觸發(fā)動(dòng)畫,執(zhí)行的位置 _controller.animateTo()
在列表數(shù)據(jù)當(dāng)中給動(dòng)畫標(biāo)記字段,讓其是否執(zhí)行動(dòng)畫;當(dāng)用戶投票成功,改變狀態(tài)執(zhí)行進(jìn)度條動(dòng)畫。用戶滑動(dòng)列表之后,將標(biāo)記改為false。關(guān)閉動(dòng)畫效果。
針對(duì)修改部分源碼,設(shè)置進(jìn)度條圓角控件;
import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class RoundLinearProgressPainter extends ProgressIndicator { const RoundLinearProgressPainter({ Key key, double value, Color backgroundColor, Color color, Animation<Color> valueColor, this.minHeight, String semanticsLabel, String semanticsValue, }) : assert(minHeight == null || minHeight > 0), super( key: key, value: value, backgroundColor: backgroundColor, color: color, valueColor: valueColor, semanticsLabel: semanticsLabel, semanticsValue: semanticsValue, ); final double minHeight; @override _RoundLinearProgressPainterState createState() => _RoundLinearProgressPainterState(); } class _RoundLinearProgressPainterState extends State<RoundLinearProgressPainter> with SingleTickerProviderStateMixin { AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 1), vsync: this, )..addListener(() { setState(() {}); }); if (widget.value != null) _controller.forward(); } @override Widget build(BuildContext context) { return widget._buildSemanticsWrapper( context: context, child: Container( constraints: BoxConstraints( minWidth: double.infinity, minHeight: widget.minHeight ?? 4.0, ), child: CustomPaint( painter: _LinearProgressIndicatorPainter( backgroundColor: widget._getBackgroundColor(context), valueColor: widget._getValueColor(context), value: widget.value, animationValue: _controller.value, ), ), ), ); } @override void didUpdateWidget(RoundLinearProgressPainter oldWidget) { super.didUpdateWidget(oldWidget); if (widget.value == null && !_controller.isAnimating) _controller.repeat(); else if (widget.value != null && _controller.isAnimating) _controller.stop(); } @override void dispose() { _controller.dispose(); super.dispose(); } } class _LinearProgressIndicatorPainter extends CustomPainter { const _LinearProgressIndicatorPainter({ this.backgroundColor, this.valueColor, this.value, this.animationValue, }); final Color backgroundColor; final Color valueColor; final double value; final double animationValue; @override void paint(Canvas canvas, Size size) { final Paint paint = Paint() ..color = backgroundColor ..isAntiAlias = true ..style = PaintingStyle.fill; canvas.drawRect(Offset.zero & size, paint); paint.color = valueColor; void drawBar(double x, double width) { if (width <= 0.0) return; RRect rRect; ///圓角的寬度 var radius = Radius.circular(8.w); if (value == 1.0) { ///當(dāng)進(jìn)度條為1時(shí),設(shè)置四周圓角 rRect = RRect.fromRectAndRadius( Offset(0.0, 0.0) & Size(width, size.height), radius); } else { ///小于1時(shí),設(shè)置左側(cè)圓角 rRect = RRect.fromRectAndCorners( Offset(0.0, 0.0) & Size(width, size.height), topLeft: radius, bottomLeft: radius); } canvas.drawRRect(rRect, paint); } if (value != null) { drawBar(0.0, value.clamp(0.0, 1.0) * size.width); } } @override bool shouldRepaint(_LinearProgressIndicatorPainter oldPainter) { return oldPainter.backgroundColor != backgroundColor || oldPainter.valueColor != valueColor || oldPainter.value != value || oldPainter.animationValue != animationValue; } } abstract class ProgressIndicator extends StatefulWidget { const ProgressIndicator({ Key key, this.value, this.backgroundColor, this.color, this.valueColor, this.semanticsLabel, this.semanticsValue, }) : super(key: key); final double value; final Color backgroundColor; final Color color; final Animation<Color> valueColor; final String semanticsLabel; final String semanticsValue; Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Theme.of(context).colorScheme.background; Color _getValueColor(BuildContext context) => valueColor?.value ?? color ?? Theme.of(context).colorScheme.primary; @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties.add(PercentProperty('value', value, showName: false, ifNull: '<indeterminate>')); } Widget _buildSemanticsWrapper({ BuildContext context, Widget child, }) { String expandedSemanticsValue = semanticsValue; if (value != null) { expandedSemanticsValue ??= '${(value * 100).round()}%'; } return Semantics( label: semanticsLabel, value: expandedSemanticsValue, child: child, ); } }
以上就是“Flutter投票組件如何使用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。