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
                  }),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}