Flutter开发日记——Flutter动画&Motion Widget详解(下)

本篇文章已授权微信公众号 YYGeeker 独家发布转载请标明出处

AnimatedDefaultTextStyle

1、简介

  • AnimatedDefaultTextStyle控件表示一个具有变化文本样式的动画控件
  • AnimatedDefaultTextStyle通过修改组件的style属性,系统将会通过动画的方式自动切换到新的style样式

2、构造函数

AnimatedDefaultTextStyle({
    Key key,
    @required this.child,
    @required this.style,
    this.textAlign,
    this.softWrap = true,
    this.overflow = TextOverflow.clip,
    this.maxLines,
    Curve curve = Curves.linear,
    @required Duration duration,
    Duration reverseDuration,
})
  • child:子控件,通常用Text组件
  • style:子控件的样式,用于动画变化
  • textAlign:如果文本超过1行时,所有换行的字体的对齐方式,可以是左对齐、右对齐
  • softWrap:文本是否应该在软换行符处换行,软换行和硬换行是word用法,具体自阅
  • overflow:超过文本行数区域的裁剪方式
  • maxLines:文本最大行数,默认是1
  • curve:动画插值器
  • duration:动画播放时长
  • reverseDuration:倒退动画播放时长

3、例子

通过_isSelected的值控制样式的切换

AnimatedDefaultTextStyle(
  softWrap: false,
  textAlign: TextAlign.right,
  maxLines: 2,
  overflow: TextOverflow.ellipsis,
  curve: Curves.linear,
  duration: Duration(seconds: 1),
  child: Text("Flutter message you!!!"),
  style: _isSelected
      ? TextStyle(
          fontSize: 10.0,
          color: Colors.red,
          fontWeight: FontWeight.bold,
        )
      : TextStyle(
          fontSize: 50.0,
          color: Colors.black,
          fontWeight: FontWeight.w300,
        ),
),

通过计时器控制样式的切换

Timer.periodic(Duration(seconds: 1), (timer) {
  setState(() {
    switch (time % 4) {
      case 0:
        _isSelected = false;
        break;
      case 2:
        _isSelected = true;
        break;
    }
    time++;
  });
});

在这里插入图片描述

AnimatedListState/AnimatedList

1、简介

  • AnimatedListState控件表示一个具有动画的列表控件
  • AnimatedListState控件作为AnimatedList控件的key进行使用,可以控制列表动画和增删操作

2、构造函数

const AnimatedList({
    Key key,
    @required this.itemBuilder,
    this.initialItemCount = 0,
    this.scrollDirection = Axis.vertical,
    this.reverse = false,
    this.controller,
    this.primary,
    this.physics,
    this.shrinkWrap = false,
    this.padding,
})
  • itemBuilder:列表条目的构建者
  • initialItemCount:列表初始化条目的个数
  • scrollDirection:滚动的方向
  • reverse:是否翻转
  • controller:滚动控制器
  • primary:是否当用户点击状态栏时,该视图会滚动到顶部,只适用于iOS,默认支持
  • physics:控制用户滚动视图的交互
    • AlwaysScrollableScrollPhysics:列表总是可滚动的
    • PageScrollPhysics:一页一页的列表滑动,一般用于PageView控件用的滑动效果,滑动到末尾会有比较大的弹起
    • ClampingScrollPhysics:滚动时没有回弹效果
    • NeverScrollableScrollPhysics:就算内容超过列表范围也不会滑动
    • BouncingScrollPhysics:不论什么平台都会有回弹效果
    • FixedExtentScrollPhysics:仅滚动到子项而不存在任何偏移,必须与使用FixedExtentScrollController的可滚动对象一起使用
  • shrinkWrap:是否根据子widget的总长度来设置ListView的长度
  • padding:父控件的内边距

3、例子

通过点击加号随机生成字符串,对列表进行增加操作,通过点击条目的删除图标,对列表进行删除操作

class WeWidgetState extends State<WeWidget> {
  var data = <String>[];
  var tween = Tween<Offset>(begin: Offset(1, 0), end: Offset(0, 0));
  final animatedKey = GlobalKey<AnimatedListState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('day19'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          var str = Random().nextInt(1000).toString();
          data.add(str);
          var index = data.lastIndexOf(str);
          animatedKey.currentState.insertItem(index);
        },
        child: Icon(Icons.add),
      ),
      body: AnimatedList(
        physics: BouncingScrollPhysics(),
        padding: EdgeInsets.all(12.0),
        scrollDirection: Axis.vertical,
        primary: true,
        reverse: false,
        shrinkWrap: false,
        key: animatedKey,
        initialItemCount: data.length,
        itemBuilder: (context, int index, Animation<double> animation) {
          return animationListItem(data[index], animation);
        },
      ),
    );
  }

  Widget animationListItem(String str, animation) {
    return SlideTransition(
      position: animation.drive(tween),
      child: listItem(str),
    );
  }

  Widget listItem(String str) {
    return ListTile(
      title: Text('$str', style: TextStyle(fontSize: 30)),
      trailing: IconButton(
        icon: Icon(Icons.delete_forever),
        onPressed: () {
          var index = data.indexOf(str);
          data.remove(str);
          animatedKey.currentState.removeItem(
              index, (context, animation) => animationListItem(str, animation));
        },
      ),
    );
  }
}

在这里插入图片描述

AnimatedModalBarrier

1、简介

  • AnimatedModalBarrier控件表示一个具有颜色值变化的动画控件
  • AnimatedModalBarrier控件可防止用户与其自身背后的小部件进行交互,并且可以使用颜色动画进行过渡
  • AnimatedModalBarrier控件举例说明,当屏幕上出现对话框时,对话框下方的页面通常会被ModalBarrier变暗

2、构造函数

const AnimatedModalBarrier({
    Key key,
    Animation<Color> color,
    this.dismissible = true,
    this.semanticsLabel,
    this.barrierSemanticsDismissible,
})
  • color:颜色值动画变化
  • dismissible:是否触摸当前ModalBarrier将弹出当前路由,配合点击事件弹出路由使用
  • semanticsLabel:语义化标签
  • barrierSemanticsDismissible:语义树中是否包括ModalBarrier语义

3、例子

Widget _buildColumn() {
    return Center(
      child: Container(
        width: 200,
        height: 200,
        child: AnimatedModalBarrier(
          semanticsLabel: "StackBarrier",
          barrierSemanticsDismissible: true,
          dismissible: true,
          color: _animation,
        ),
      ),
    );
}

在这里插入图片描述

AnimatedOpacity

1、简介

  • AnimatedOpacity控件表示一个具有透明度变化的动画控件

2、构造函数

const AnimatedOpacity({
    Key key,
    this.child,
    @required this.opacity,
    Curve curve = Curves.linear,
    @required Duration duration,
})
  • child:子控件
  • opacity:透明度动画变化值
  • curve:动画的插值器
  • duration:动画的时长

3、例子

通过定时器改变透明度的大小

class WeWidgetState extends State<WeWidget> {
  WeWidgetState() {
    Timer.periodic(Duration(milliseconds: 1000), (timer) {
      setState(() {
        switch (time % 2) {
          case 0:
            _opacity = 0.3;
            break;
          case 1:
            _opacity = 1.0;
            break;
        }
        time++;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("day21"),
      ),
      body: _buildColumn(),
    );
  }

  Widget _buildColumn() {
    return Center(
      child: AnimatedOpacity(
        curve: Curves.fastOutSlowIn,
        opacity: _opacity,
        duration: Duration(seconds: 1),
        child: FlutterLogo(
          style: FlutterLogoStyle.horizontal,
          size: 200,
        ),
      ),
    );
  }
}

在这里插入图片描述

AnimatedPhysicalModel

1、简介

  • AnimatedPhysicalModel控件表示一个具有阴影背景动画的控件

2、构造函数

const AnimatedPhysicalModel({
    Key key,
    @required this.child,
    @required this.shape,
    this.clipBehavior = Clip.none,
    this.borderRadius = BorderRadius.zero,
    @required this.elevation,
    @required this.color,
    this.animateColor = true,
    @required this.shadowColor,
    this.animateShadowColor = true,
    Curve curve = Curves.linear,
    @required Duration duration,
})
  • child:子控件
  • shape:阴影的形状
  • clipBehavior:阴影的裁剪方式
    • Clip.none:无模式
    • Clip.hardEdge:裁剪速度稍快,但容易失真,有锯齿
    • Clip.antiAlias:裁剪边缘抗锯齿,使得裁剪更平滑,这种模式裁剪速度比antiAliasWithSaveLayer快,但是比hardEdge慢
    • Clip.antiAliasWithSaveLayer:裁剪后具有抗锯齿特性并分配屏幕缓冲区,所有后续操作在缓冲区进行
  • borderRadius:背景的边框
  • elevation:阴影颜色值的深度
  • color:背景色
  • animateColor:背景色是否用动画形式展示
  • shadowColor:阴影的动画值
  • animateShadowColor:阴影是否用动画形式展示
  • curve:动画的插值器
  • duration:动画的时长

3、例子

Widget _buildColumn() {
    return Center(
      child: AnimatedPhysicalModel(
        curve: Curves.fastOutSlowIn,
        color: Colors.grey.withOpacity(0.2),
        clipBehavior: Clip.antiAliasWithSaveLayer,
        borderRadius: BorderRadius.circular(12.0),
        animateColor: true,
        animateShadowColor: true,
        shape: BoxShape.rectangle,
        shadowColor: _shadowColor,
        elevation: 20.0,
        duration: Duration(seconds: 1),
        child: FlutterLogo(
          style: FlutterLogoStyle.horizontal,
          size: 200,
        ),
      ),
    );
  }

在这里插入图片描述

AnimatedPositioned

1、简介

  • AnimatedPositioned控件表示一个具有位置变化动画的控件

2、构造函数

const AnimatedPositioned({
    Key key,
    @required this.child,
    this.left,
    this.top,
    this.right,
    this.bottom,
    this.width,
    this.height,
    Curve curve = Curves.linear,
    @required Duration duration,
})
  • child:子控件
  • left:左边距离
  • top:上边距离
  • right:右边距离
  • bottom:下边距离
  • width:控件的宽度
  • height:控件的高度
  • curve:动画的插值器
  • duration:动画的时长

3、例子

通过改变左上角位置和宽高进行动画播放

class WeWidgetState extends State<WeWidget> {
  WeWidgetState() {
    Timer.periodic(Duration(milliseconds: 1000), (timer) {
      setState(() {
        switch (time % 2) {
          case 0:
            _width = 100.0;
            break;
          case 1:
            _width = 200.0;
            break;
        }
        time++;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("day23"),
      ),
      body: _buildColumn(),
    );
  }

  Widget _buildColumn() {
    return Stack(
      children: <Widget>[
        AnimatedPositioned(
          curve: Curves.fastOutSlowIn,
          width: _width,
          height: _width,
          top: _width,
          left: _width,
          duration: Duration(seconds: 1),
          child: FlutterLogo(
            style: FlutterLogoStyle.horizontal,
            size: 200,
          ),
        ),
      ],
    );
  }
}

在这里插入图片描述

AnimatedSize

1、简介

  • AnimatedSize控件表示一个具有尺寸变化动画的控件

2、构造函数

const AnimatedSize({
    Key key,
    Widget child,
    this.alignment = Alignment.center,
    this.curve = Curves.linear,
    @required this.duration,
    this.reverseDuration,
    @required this.vsync,
})
  • child:子控件
  • alignment:子控件的对齐方式
  • curve:动画的插值器
  • duration:动画的时长
  • reverseDuration:翻转动画的时长
  • vsync:是否开启垂直同步

3、例子

class WeWidgetState extends State<WeWidget>
    with SingleTickerProviderStateMixin {
  WeWidgetState() {
    Timer.periodic(Duration(milliseconds: 1000), (timer) {
      setState(() {
        switch (time % 2) {
          case 0:
            _width = 100.0;
            break;
          case 1:
            _width = 200.0;
            break;
        }
        time++;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("day24"),
      ),
      body: _buildColumn(),
    );
  }

  Widget _buildColumn() {
    return Center(
      child: AnimatedSize(
        alignment: Alignment.center,
        curve: Curves.fastOutSlowIn,
        vsync: this,
        duration: Duration(seconds: 1),
        reverseDuration: Duration(seconds: 2),
        child: FlutterLogo(
          style: FlutterLogoStyle.horizontal,
          size: _width,
        ),
      ),
    );
  }
}

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Flutter是一种UI工具包,可以用来开发高性能、高保真度的应用程序。随着Flutter的日益普及,越来越多的开发者开始使用Flutter开发应用程序。在这样的背景下,Flutter开发实战详解这本书,为众多开发人员提供了实践性非常强的经验分享和技术指导。 这本书内容丰富,从基础概念、环境设置,到实际开发应用程序都进行了详细介绍。读完本书,读者将会具有: 1. Flutter跨平台应用开发的核心技能:包括组件库、布局、状态管理、动画、网络、数据储存等核心技能。这些技能对于任何一个Flutter开发者都是必备的。 2. 实际项目开发经验:本书包含大量搭建实际应用程序的案例分析和实例演练。通过学习这些案例,读者将会了解如何解决实际开发应用程序中所遇到的各种问题,如调试、性能优化、部署等等。 3. 高质量UI设计:本书通过实例讲解了在Flutter中如何实现高质量和美观的UI设计,并向读者展示了如何借鉴开源组件库并构建自己的一套用户界面组件库。 总之,Flutter开发实战详解这本书是适合所有Flutter开发者的一本经典著作。如果您想要成为一名熟练的跨平台应用程序开发者,那么这本书绝对值得阅读和好好学习。 ### 回答2: Flutter开发实战详解是一本非常实用的书,书中涵盖了Flutter开发基础、组件使用、实战应用等方面的知识。对于想要学习Flutter开发者来说,这本书具有非常实用的指导意义。在教学方面,本书使用了简单易懂、详细生动的语言,配合大量的实战案例和代码示例,让读者能够更加深入地理解Flutter开发方式和设计模式,掌握如何使用Flutter开发应用程序。书中还介绍了如何创建一个Flutter项目,如何使用Flutter中的UI组件和动画,以及如何使用Flutter中的第三方库来扩展应用功能等内容,让读者能够通过实践快速掌握Flutter开发技能。总之,Flutter开发实战详解是一本非常优秀的Flutter开发进阶书籍,主要针对于那些已经掌握了基础知识,并想进一步深入学习Flutter开发实践的开发者,不论是初学者还是进阶者,都值得一读。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

许英俊潇洒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值