Flutter投票組件使用方法詳解
更新時間:2022年08月24日 09:09:37 作者:懷君
這篇文章主要為大家詳細介紹了Flutter投票組件的使用方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了Flutter投票組件的使用方法,供大家參考,具體內容如下
前景
基于公司項目需求,仿照微博實現投票功能。
開發(fā)遇到的問題
1.選項列表的高度,自適應的問題;
2.進度條動畫的問題;
3.列表回收機制,導致進度條動畫重復;
4.自定義進度條四周圓角;
如何解決問題
- 拿到數組列表最長的數據,然后根據屏幕寬度計算,超出一行則設定兩行高度,否則使用一行的高度;
_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) {
? ? //設置item選項的高度
? ? ? _itemHeight = 100.w;
? ? }
? }- Widget控件初始化(initState)方法時,使用AnimationController動畫,并實現SingleTickerProviderStateMixin,在build方法當中調用 _controller.animateTo()
AnimationController _controller;
? ? _controller = AnimationController(
? ? ? vsync: this,
? ? ? duration: const Duration(seconds: 1),
? ? )..addListener(() {
? ? ? ? setState(() {});
? ? ? });
//觸發(fā)動畫,執(zhí)行的位置
_controller.animateTo()- 在列表數據當中給動畫標記字段,讓其是否執(zhí)行動畫;當用戶投票成功,改變狀態(tài)執(zhí)行進度條動畫。用戶滑動列表之后,將標記改為false。關閉動畫效果。
- 針對修改部分源碼,設置進度條圓角控件;
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) {
? ? ? ///當進度條為1時,設置四周圓角
? ? ? ? rRect = RRect.fromRectAndRadius(
? ? ? ? ? ? Offset(0.0, 0.0) & Size(width, size.height), radius);
? ? ? } else {
? ? ? ? ///小于1時,設置左側圓角
? ? ? ? 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,
? ? );
? }
}以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
打飛機游戲終極BOSS Android實戰(zhàn)打飛機游戲完結篇
打飛機游戲終極BOSS,Android實戰(zhàn)打飛機游戲完結篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-07-07
Mac 下 Android Studio 不打印日志的解決辦法
這篇文章主要介紹了Mac 下 Android Studio 不打印日志的解決辦法的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-10-10

