溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter投票組件如何使用

發布時間:2022-08-24 10:39:12 來源:億速云 閱讀:161 作者:iii 欄目:開發技術

今天小編給大家分享一下Flutter投票組件如何使用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

開發遇到的問題

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(() {});
      });
//觸發動畫,執行的位置
_controller.animateTo()
  • 在列表數據當中給動畫標記字段,讓其是否執行動畫;當用戶投票成功,改變狀態執行進度條動畫。用戶滑動列表之后,將標記改為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,
    );
  }
}

以上就是“Flutter投票組件如何使用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女