網站首頁 編程語言 正文
本文實例為大家分享了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,
? ? );
? }
}
原文鏈接:https://blog.csdn.net/u013290250/article/details/120484975
相關推薦
- 2022-11-30 react源碼層探究setState作用_React
- 2022-07-06 pandas如何統計某一列或某一行的缺失值數目_python
- 2023-12-21 JDBC中ResultSet的使用
- 2022-10-01 C#?將?Stream?保存到文件的方法_C#教程
- 2022-07-08 C#實現收發郵件功能_C#教程
- 2022-11-05 Android開發RecyclerView實現折線圖效果_Android
- 2023-03-26 React性能優化的實現方法詳解_React
- 2022-07-16 MyBatis查詢時數據表字段名與實體類屬性名不一致
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支