Dart 在flatter中创建自定义时钟小部件
我的目标是创造一个类似的时钟。如何使用颤振实现它 我推荐的是,和教程。这也是一个很好的方式来学习你周围的颤振方式 下面是如何构建应用程序的示意图Dart 在flatter中创建自定义时钟小部件,dart,flutter,Dart,Flutter,我的目标是创造一个类似的时钟。如何使用颤振实现它 我推荐的是,和教程。这也是一个很好的方式来学习你周围的颤振方式 下面是如何构建应用程序的示意图 导入'dart:math'作为数学; 导入“package:meta/meta.dart”; 进口“包装:颤振/材料.省道”; void main(){ runApp(新材料)PP( 主题:新主题数据( 画布颜色:颜色。深紫色, iconTheme:new IconThemeData(颜色:Colors.white), accentColor:Col
导入'dart:math'作为数学;
导入“package:meta/meta.dart”;
进口“包装:颤振/材料.省道”;
void main(){
runApp(新材料)PP(
主题:新主题数据(
画布颜色:颜色。深紫色,
iconTheme:new IconThemeData(颜色:Colors.white),
accentColor:Colors.pinkAccent,
亮度:亮度。暗,
),
主页:新建MyHomePage(),
));
}
类ProgressPainter扩展了CustomPainter{
进步画家({
@需要这个动画,
@需要这个。背景色,
@需要这个颜色,
}):super(重新绘制:动画);
///表示我们正在绘制的内容的动画
最终动画;
///圆圈背景中的颜色
最终颜色背景色;
///用于指示进度的前景色
最终颜色;
@凌驾
空心油漆(帆布,尺寸){
油漆=新油漆()
…颜色=背景颜色
..冲程宽度=5.0
..strokeCap=strokeCap.round
..风格=绘画风格.笔划;
画布.画圈(大小.中心(偏移.零),大小.宽度/2.0,绘制);
paint.color=颜色;
double progressRadians=(1.0-animation.value)*2*math.pi;
帆布拉弧(
偏移量0和尺寸,数学pi*1.5,-弧度,假,油漆);
}
@凌驾
bool应重新喷漆(其他){
返回animation.value!=其他.animation.value||
颜色||
backgroundColor!=其他.backgroundColor;
}
}
类MyHomePage扩展StatefulWidget{
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState使用TickerProviderStateMixin扩展状态{
列表图标=[
Icons.alarm、Icons.access\u time、Icons.沙漏\u empty、Icons.timer、,
];
动画控制器_控制器;
字符串获取剩余时间{
持续时间=_controller.Duration*_controller.value;
返回${duration.inMinutes}${(duration.insectonds%60)
.toString()
.padLeft(2,'0')}';
}
@凌驾
void initState(){
super.initState();
_控制器=新的AnimationController(
vsync:这个,,
持续时间:常数持续时间(秒数:12),
)
..反向(从0.4开始);
}
小部件构建(构建上下文){
MEMEDATA MEMEDATA=Theme.of(上下文);
归还新脚手架(
车身:新衬垫(
填充:常数边集全部(10.0),
儿童:
新专栏(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
儿童:[
新行(
mainAxisAlignment:mainAxisAlignment.start,
子项:icons.map((iconda iconda){
退回新货柜(
边距:所有新边集(10.0),
孩子:新的图标按钮(
图标:新图标(iconData),按下时:(){
//TODO:实现
}),
);
}).toList(),
),
新扩展(
子:新对齐(
对齐:分馏loffset.center,
孩子:新的方面(
aspectRatio:1.0,
子:新堆栈(
儿童:[
新定位填充(
子对象:新的动画生成器(
动画:_控制器,
生成器:(BuildContext上下文,小部件子项){
返回新的CustomPaint(
画家:新画家(
动画:_控制器,
颜色:主题数据。指示颜色,
背景颜色:Colors.white,
),
);
}
),
),
新对齐(
对齐:分馏loffset.center,
子:新列(
mainAxisAlignment:mainAxisAlignment.space,
crossAxisAlignment:crossAxisAlignment.center,
儿童:[
新文本(
“标签”,样式:主题数据.textTheme.subhead),
新动画生成器(
动画:_控制器,
生成器:(BuildContext上下文,小部件子项){
返回新文本(
剩余时间,
样式:themeData.textTheme.display4,
);
}
),
新文本(“+1”,样式:themeData.textTheme.title),
],
),
),
],
),
),
),
),
新容器(
边距:所有新边集(10.0),
孩子:新的一排(
mainAxisAlignment:mainAxisAlignment.space,
儿童:[
新建图标按钮(图标:新建图标(Icons.delete),打开按钮:(){
//TODO:实现删除
}),
新浮动操作按钮(
子对象:新的动画生成器(
动画:_控制器,
生成器:(BuildContext上下文,小部件子项){
返回新图标(
_控制器。正在初始化
?图标。暂停
import 'dart:math' as math;
import 'package:meta/meta.dart';
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
theme: new ThemeData(
canvasColor: Colors.deepPurple,
iconTheme: new IconThemeData(color: Colors.white),
accentColor: Colors.pinkAccent,
brightness: Brightness.dark,
),
home: new MyHomePage(),
));
}
class ProgressPainter extends CustomPainter {
ProgressPainter({
@required this.animation,
@required this.backgroundColor,
@required this.color,
}) : super(repaint: animation);
/// Animation representing what we are painting
final Animation<double> animation;
/// The color in the background of the circle
final Color backgroundColor;
/// The foreground color used to indicate progress
final Color color;
@override
void paint(Canvas canvas, Size size) {
Paint paint = new Paint()
..color = backgroundColor
..strokeWidth = 5.0
..strokeCap = StrokeCap.round
..style = PaintingStyle.stroke;
canvas.drawCircle(size.center(Offset.zero), size.width / 2.0, paint);
paint.color = color;
double progressRadians = (1.0 - animation.value) * 2 * math.pi;
canvas.drawArc(
Offset.zero & size, math.pi * 1.5, -progressRadians, false, paint);
}
@override
bool shouldRepaint(ProgressPainter other) {
return animation.value != other.animation.value ||
color != other.color ||
backgroundColor != other.backgroundColor;
}
}
class MyHomePage extends StatefulWidget {
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
List<IconData> icons = <IconData>[
Icons.alarm, Icons.access_time, Icons.hourglass_empty, Icons.timer,
];
AnimationController _controller;
String get timeRemaining {
Duration duration = _controller.duration * _controller.value;
return '${duration.inMinutes} ${(duration.inSeconds % 60)
.toString()
.padLeft(2, '0')}';
}
@override
void initState() {
super.initState();
_controller = new AnimationController(
vsync: this,
duration: const Duration(seconds: 12),
)
..reverse(from: 0.4);
}
Widget build(BuildContext context) {
ThemeData themeData = Theme.of(context);
return new Scaffold(
body: new Padding(
padding: const EdgeInsets.all(10.0),
child:
new Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: icons.map((IconData iconData) {
return new Container(
margin: new EdgeInsets.all(10.0),
child: new IconButton(
icon: new Icon(iconData), onPressed: () {
// TODO: Implement
}),
);
}).toList(),
),
new Expanded(
child: new Align(
alignment: FractionalOffset.center,
child: new AspectRatio(
aspectRatio: 1.0,
child: new Stack(
children: <Widget>[
new Positioned.fill(
child: new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return new CustomPaint(
painter: new ProgressPainter(
animation: _controller,
color: themeData.indicatorColor,
backgroundColor: Colors.white,
),
);
}
),
),
new Align(
alignment: FractionalOffset.center,
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
new Text(
'Label', style: themeData.textTheme.subhead),
new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return new Text(
timeRemaining,
style: themeData.textTheme.display4,
);
}
),
new Text('+1', style: themeData.textTheme.title),
],
),
),
],
),
),
),
),
new Container(
margin: new EdgeInsets.all(10.0),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new IconButton(icon: new Icon(Icons.delete), onPressed: () {
// TODO: Implement delete
}),
new FloatingActionButton(
child: new AnimatedBuilder(
animation: _controller,
builder: (BuildContext context, Widget child) {
return new Icon(
_controller.isAnimating
? Icons.pause
: Icons.play_arrow
);
},
),
onPressed: () {
if (_controller.isAnimating)
_controller.stop();
else {
_controller.reverse(
from: _controller.value == 0.0 ? 1.0 : _controller
.value,
);
}
},
),
new IconButton(
icon: new Icon(Icons.alarm_add), onPressed: () {
// TODO: Implement add time
}),
],
),
),
],
),
),
);
}
}