如何使颤动中的滚动计数器 [英] How to make scrolling counter in flutter
问题描述
我想创建一个滚动计数器,我想知道如何在flutter中实现它.
我想在项目中执行此操作,因此我创建了一个称为 AnimatedFlipCounter
的隐式动画小部件,该控件实现了类似的效果./p>
用法:
AnimatedFlipCounter(持续时间:持续时间(毫秒:500),值:_value,/*传递数字,例如2014 */颜色:黑色.大小:100,)
源代码(无null安全):
只需将以下内容复制并粘贴到文件中,然后像上面的示例一样使用 AnimatedFlipCounter
.
import'package:flutter/cupertino.dart';导入'package:flutter/material.dart';类AnimatedFlipCounter扩展了StatelessWidget {最终的int值;最终持续时间;最终双倍大小;最终颜色const AnimatedFlipCounter({关键@需要this.value,@需要this.duration,this.size = 72,this.color = Colors.black,}):super(key:key);@override窗口小部件build(BuildContext context){List< int>位=值== 0?[0]:[];int v =值;如果(v< 0){v * = -1;}而(v> 0){digits.add(v);v = v〜/10;}返回行(mainAxisSize:MainAxisSize.min,子代:List.generate(digits.length,(int i){返回_SingleDigitFlipCounter(键:ValueKey(digits.length-i),值:digits [digits.length-i-1] .toDouble(),持续时间:持续时间,高度:大小,宽度:尺寸/1.8,颜色:);}),);}}_SingleDigitFlipCounter类扩展了StatelessWidget {最终的双精度值;最终持续时间;最终双倍高度;最终双倍宽度;最终颜色const _SingleDigitFlipCounter({关键@需要this.value,@需要this.duration,@需要this.height,@需要this.width,@需要this.color,}):super(key:key);@override窗口小部件build(BuildContext context){返回TweenAnimationBuilder(补间:补间(开始:值,结束:值),持续时间:持续时间,生成器:(上下文,值,子项){最终整数=值〜/1;最后的小数=值-整数;返回SizedBox(高度:高度宽度:宽度,子代:Stack(适合:StackFit.expand,子代:< Widget> [_buildSingleDigit(数字:整数%10,偏移量:高度*小数,不透明度:1-十进制,),_buildSingleDigit(位数:(整体+ 1)%10,偏移量:高度*小数-高度,不透明度:十进制,),],),);},);}小部件_buildSingleDigit({int digit,double offset,double opacity}){返回定位(子代:SizedBox(宽度:宽度,子:不透明度(不透明度:不透明度,子代:文字("$ digit",样式:TextStyle(字体大小:高度,颜色:颜色),textAlign:TextAlign.center,),),),下:偏移量,);}}
具有空安全性的源代码::
在Flutter 2.0发行版中,您可能想使用null安全版本.
import'package:flutter/material.dart';类AnimatedFlipCounter扩展StatelessWidget {最终的int值;最终持续时间;最终双倍大小;最终颜色textColor;const AnimatedFlipCounter({钥匙?钥匙,需要this.value,需要这个持续时间,this.size = 100,this.textColor = Colors.black,}):super(key:key);@override窗口小部件build(BuildContext context){List< int>位=值== 0?[0]:[];int v =值;如果(v< 0){v * = -1;}而(v> 0){digits.add(v);v = v〜/10;}返回行(mainAxisSize:MainAxisSize.min,子代:List.generate(digits.length,(int i){返回_SingleDigitFlipCounter(键:ValueKey(digits.length-i),值:digits [digits.length-i-1] .toDouble(),持续时间:持续时间,高度:大小,宽度:尺寸/1.8,颜色:textColor,);}),);}}_SingleDigitFlipCounter类扩展了StatelessWidget {最终的双精度值;最终持续时间;最终双倍高度;最终双倍宽度;最终颜色const _SingleDigitFlipCounter({钥匙?钥匙,需要this.value,需要这个持续时间,需要这个高度.需要this.width,需要this.color,}):super(key:key);@override窗口小部件build(BuildContext context){返回TweenAnimationBuilder(补间:补间(开始:值,结束:值),持续时间:持续时间,生成器:(上下文,双精度值,子代){最终整数=值〜/1;最后的小数=值-整数;返回SizedBox(高度:高度宽度:宽度,子代:Stack(子代:< Widget> [_buildSingleDigit(数字:整数%10,偏移量:高度*小数,不透明度:1-十进制,),_buildSingleDigit(位数:(整体+ 1)%10,偏移量:高度*小数-高度,不透明度:十进制,),],),);},);}小部件_buildSingleDigit({所需的整数位,需要双偏移量需要双重不透明性}){返回定位(下:偏移量,子代:文字("$ digit",样式:TextStyle(fontSize:高度,颜色:color.withOpacity(opacity),),),);}}
I would like to create a scrolling counter and I'm wondering on how to implement this in flutter.
I wanted to do this in a project, so I create an implicit animation widget, called AnimatedFlipCounter
, that achieves similar effect.
Usage:
AnimatedFlipCounter(
duration: Duration(milliseconds: 500),
value: _value, /* pass in a number like 2014 */
color: Colors.black,
size: 100,
)
Source code (without null-safety):
Just copy and paste the following into a file, and use the AnimatedFlipCounter
like above example.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class AnimatedFlipCounter extends StatelessWidget {
final int value;
final Duration duration;
final double size;
final Color color;
const AnimatedFlipCounter({
Key key,
@required this.value,
@required this.duration,
this.size = 72,
this.color = Colors.black,
}) : super(key: key);
@override
Widget build(BuildContext context) {
List<int> digits = value == 0 ? [0] : [];
int v = value;
if (v < 0) {
v *= -1;
}
while (v > 0) {
digits.add(v);
v = v ~/ 10;
}
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(digits.length, (int i) {
return _SingleDigitFlipCounter(
key: ValueKey(digits.length - i),
value: digits[digits.length - i - 1].toDouble(),
duration: duration,
height: size,
width: size / 1.8,
color: color,
);
}),
);
}
}
class _SingleDigitFlipCounter extends StatelessWidget {
final double value;
final Duration duration;
final double height;
final double width;
final Color color;
const _SingleDigitFlipCounter({
Key key,
@required this.value,
@required this.duration,
@required this.height,
@required this.width,
@required this.color,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder(
tween: Tween(begin: value, end: value),
duration: duration,
builder: (context, value, child) {
final whole = value ~/ 1;
final decimal = value - whole;
return SizedBox(
height: height,
width: width,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
_buildSingleDigit(
digit: whole % 10,
offset: height * decimal,
opacity: 1 - decimal,
),
_buildSingleDigit(
digit: (whole + 1) % 10,
offset: height * decimal - height,
opacity: decimal,
),
],
),
);
},
);
}
Widget _buildSingleDigit({int digit, double offset, double opacity}) {
return Positioned(
child: SizedBox(
width: width,
child: Opacity(
opacity: opacity,
child: Text(
"$digit",
style: TextStyle(fontSize: height, color: color),
textAlign: TextAlign.center,
),
),
),
bottom: offset,
);
}
}
Source code with null-safety::
With the release of Flutter 2.0, you might want to use the null-safety version instead.
import 'package:flutter/material.dart';
class AnimatedFlipCounter extends StatelessWidget {
final int value;
final Duration duration;
final double size;
final Color textColor;
const AnimatedFlipCounter({
Key? key,
required this.value,
required this.duration,
this.size = 100,
this.textColor = Colors.black,
}) : super(key: key);
@override
Widget build(BuildContext context) {
List<int> digits = value == 0 ? [0] : [];
int v = value;
if (v < 0) {
v *= -1;
}
while (v > 0) {
digits.add(v);
v = v ~/ 10;
}
return Row(
mainAxisSize: MainAxisSize.min,
children: List.generate(digits.length, (int i) {
return _SingleDigitFlipCounter(
key: ValueKey(digits.length - i),
value: digits[digits.length - i - 1].toDouble(),
duration: duration,
height: size,
width: size / 1.8,
color: textColor,
);
}),
);
}
}
class _SingleDigitFlipCounter extends StatelessWidget {
final double value;
final Duration duration;
final double height;
final double width;
final Color color;
const _SingleDigitFlipCounter({
Key? key,
required this.value,
required this.duration,
required this.height,
required this.width,
required this.color,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder(
tween: Tween(begin: value, end: value),
duration: duration,
builder: (context, double value, child) {
final whole = value ~/ 1;
final decimal = value - whole;
return SizedBox(
height: height,
width: width,
child: Stack(
children: <Widget>[
_buildSingleDigit(
digit: whole % 10,
offset: height * decimal,
opacity: 1 - decimal,
),
_buildSingleDigit(
digit: (whole + 1) % 10,
offset: height * decimal - height,
opacity: decimal,
),
],
),
);
},
);
}
Widget _buildSingleDigit({
required int digit,
required double offset,
required double opacity,
}) {
return Positioned(
bottom: offset,
child: Text(
"$digit",
style: TextStyle(
fontSize: height,
color: color.withOpacity(opacity),
),
),
);
}
}
这篇关于如何使颤动中的滚动计数器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!