Flutter 128: 图解 ColorTween 颜色补间动画 & ButtonBar 按钮容器

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 0 基础学习 Flutter,第一百二十八步:简单应用 ColorTween 和 ButtonBar Widgets!

    小菜在尝试做主题颜色切换时,希望背景色有一个自然的过渡过程,于是了解到 ColorTween 颜色补间差值器,配合 AnimationController 实现两种颜色间的自然过渡;小菜简单尝试一下;

ColorTween

源码分析

    ColorTween 的源码很简单,继承自 Tween 补间动画,与 Tween 相同,只是 beginendColor 替代;其中若需要透明状态,可以将 begin / end 设置为 nullColors.transparent 再此代表黑色透明,会淡入淡出黑色;

class ColorTween extends Tween<Color?> {
  ColorTween({ Color? begin, Color? end }) : super(begin: begin, end: end);

  @override
  Color? lerp(double t) => Color.lerp(begin, end, t);
}

案例源码

    小菜预先设置好需要主题颜色切换的 UI Widget,之后通过混入 TickerProviderStateMixin,在 initState() 初始化时设置好 AnimationController,将颜色传递给背景色;

AnimationController _controller;
Animation<Color> _colors;
Color _currentColor = Colors.black;

@override
void initState() {
  super.initState();
  _controller = AnimationController(duration: Duration(seconds: 3), vsync: this);
  _colors = ColorTween(begin: _currentColor, end: Colors.amber).animate(_controller);
}

_bodyWid() => Material(
    child: AnimatedBuilder(
        animation: _colors,
        builder: (BuildContext _, Widget childWidget) {
          return Scaffold(backgroundColor: _colors.value, body: _itemListWid());
        }));

    通过 AnimationController 控制淡入淡出时机;reset() 重置控制器,forward()beginend 颜色切换;reward()endbegin 颜色切换;repeat() 重复循环切换;

_changeColorWid() => Container(
    color: Colors.white,
    child: Column(children: [
      ListTile(title: Text('切换 ThemeColor:')),
      Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
        _itemColorWid(Colors.deepOrange), _itemColorWid(Colors.teal),
        _itemColorWid(Colors.blue), _itemColorWid(Colors.pink),
        _itemColorWid(Colors.indigoAccent)
      ])
    ]));

_itemColorWid(color) => GestureDetector(
    child: Container(width: 50.0, height: 50.0, color: color),
    onTap: () {
      _colors = ColorTween(begin: _currentColor, end: color).animate(_controller);
      setState(() {
        _controller.reset();
        _controller.forward();
      });
      _currentColor = color;
    });

ButtonBar

    小菜在很多场景中设置水平均分或右对齐,为此小菜了解到一个新的容器方式,ButtonBar 默认水平方式放置子 Widget 当水平宽度无法完全放置所有子 Widget 时会竖直方向放置,小菜简单学习一下;

源码分析

const ButtonBar({
    Key key,
    this.alignment,         // 对齐方式
    this.mainAxisSize,      // 主轴上占据空间范围
    this.buttonTextTheme,   // 按钮文本主题
    this.buttonMinWidth,    // 子按钮最小宽度
    this.buttonHeight,      // 子按钮最高度
    this.buttonPadding,     // 子按钮内边距
    this.buttonAlignedDropdown, // 下拉菜单是否与子按钮对齐
    this.layoutBehavior,
    this.overflowDirection, // 子按钮排列顺序
    this.overflowButtonSpacing, // 子按钮之间间距
    this.children = const <Widget>[],
})

    简单分析源码,ButtonBar 作为一个无状态的 StatelessWidgetRow 类似,作为一个存放子 Widget 的容器,其中包括了类似于对齐方式等属性方便应用;小菜简单理解为变形的 Row,实际是继承自 Flex_ButtonBarRow

案例尝试

构造方法

    ButtonBar 作为一个 Widget 容器,用于水平存放各 Widget,若子 Widget 占据空间范围大于分配空间时,则竖直方向展示;

_buttonBarWid01() => ButtonBar(children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null) ]);
    
_buttonBarWid02() => ButtonBar(children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null),
      RaisedButton(child: Text('Button 04'), onPressed: null) ]);
    
_buttonBarWid03() => ButtonBar(children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null),
      RaisedButton(child: Text('Button 04'), onPressed: null),
      RaisedButton(child: Text('Button 05'), onPressed: null) ]);

1. alignment

    alignment 为容器内子 Widget 的对齐方式,不设置或为 null 时默认为 end 方式对齐,此时与 ltr / rtl 相关;

_buttonBarWid01(index) {
  MainAxisAlignment alignment;
  if (index == 0) {
    alignment = MainAxisAlignment.start;
  } else if (index == 1) {
    alignment = MainAxisAlignment.center;
  } else if (index == 2) {
    alignment = MainAxisAlignment.spaceAround;
  } else if (index == 3) {
    alignment = MainAxisAlignment.spaceBetween;
  } else if (index == 4) {
    alignment = MainAxisAlignment.spaceEvenly;
  } else {
    alignment = MainAxisAlignment.end;
  }
  return ButtonBar(alignment: alignment, children: <Widget>[
    RaisedButton(child: Text('Button'), onPressed: null),
    RaisedButton(child: Text('${alignment.toString()}'), onPressed: null) ]);
}

2. mainAxisSize

    mainAxisSize 为主轴上占据空间范围,与 Row / Column 一致,分为 min / max 最小范围和最大填充范围两种;

_buttonBarWid05(mainAxisSize) => Container(
    color: Colors.blue.withOpacity(0.3),
    child: ButtonBar(mainAxisSize: mainAxisSize, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02'), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null)
    ]));

3. buttonTextTheme

    buttonTextTheme 为子 Widget 按钮主题,主要包括 normal / accent / primary 三种主题样式,分别对应 ThemeData.brightness / accentColor / primaryColor

_buttonBarWid04(theme) =>
    ButtonBar(buttonTextTheme: theme, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
      RaisedButton(child: Text('${theme.toString()}'), onPressed: null),
    ]);

4. buttonMinWidth & buttonHeight

    buttonMinWidth & buttonHeight 分别对应子 Widget 默认的最小按钮宽度和按钮高度;

_buttonBarWid06(width, height, alignment) =>
    ButtonBar(buttonMinWidth: width, buttonHeight: height, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
      RaisedButton(child: Text('${alignment.toString()}'), onPressed: null),
    ]);

5. overflowButtonSpacing & buttonPadding

    overflowButtonSpacing 对应子按钮外间距,类似于 GridView 元素间间距;buttonPadding 对应子按钮内边距;

_buttonBarWid07(padding, spacing) => ButtonBar(
      overflowButtonSpacing: spacing,
      buttonPadding: EdgeInsets.all(padding),
      children: <Widget>[
        RaisedButton(child: Text('Button 01'), onPressed: null),
        RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
        RaisedButton(child: Text('Button 03'), onPressed: null)
      ]);

6. overflowDirection

    overflowDirection 为若容器内子 Widget 所占范围超过最大限制范围时,垂直排列顺序,小菜理解为顺序和倒序两种;

_buttonBarWid08(direction) =>
    ButtonBar(overflowDirection: direction, children: <Widget>[
      RaisedButton(child: Text('Button 01'), onPressed: null),
      RaisedButton(child: Text('Button 02', style: TextStyle(color: Colors.blue)), onPressed: null),
      RaisedButton(child: Text('Button 03'), onPressed: null),
      RaisedButton(child: Text('${direction.toString()}'), onPressed: null),
    ]);


    ColorTween 案例源码 & ButtonBar 案例源码


    ColorTweenButtonBar 的应用非常简单,这次小菜在实际场景中进行尝试学习,如有错误,请多多指导!

来源: 阿策小和尚
目录
相关文章
|
4天前
|
Java 容器
idea中关于java的图形化界面编程awt_container容器中Button(按钮)上汉字是乱码或者小方框的解决方法
idea中关于java的图形化界面编程awt_container容器中Button(按钮)上汉字是乱码或者小方框的解决方法
55 0
|
2天前
|
数据库 Android开发
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
|
2天前
|
Web App开发 前端开发 iOS开发
CSS3 转换,深入理解Flutter动画原理,前端基础图形
CSS3 转换,深入理解Flutter动画原理,前端基础图形
|
4天前
|
前端开发 开发者 UED
【Flutter前端技术开发专栏】Flutter中的动画与过渡效果实现
【4月更文挑战第30天】Flutter UI框架以其高性能动画库著称,允许开发者轻松创建复杂动画。动画基于`Animation&lt;double&gt;`类,结合`Tween`、`Curve`和`AnimationController`实现。简单示例展示了一个点击按钮后放大效果的创建过程。此外,Flutter提供预定义动画组件和`Navigator`类实现页面过渡。`PageRouteBuilder`允许自定义过渡,而`Hero`动画则实现跨页面的平滑过渡。借助这些工具,开发者能提升应用的视觉吸引力和交互体验。
【Flutter前端技术开发专栏】Flutter中的动画与过渡效果实现
|
4天前
|
开发框架 API 开发者
Flutter的动画:实现方式与动画库的技术探索
【4月更文挑战第26天】探索Flutter动画机制与库:基础动画、自定义动画、物理动画及Lottie、AnimatedWidgets、EasyAnimations等库的应用,助开发者实现丰富动画效果,提升用户体验。同时,了解性能优化技巧,如避免重绘、利用离屏渲染和GPU加速,确保动画流畅。 Flutter为移动应用开发带来强大动画支持。
|
4天前
|
前端开发
Flutter笔记:光影动画按钮、滚动图标卡片组等
Flutter笔记:光影动画按钮、滚动图标卡片组等
42 0
|
4天前
|
iOS开发
Flutter 组件(三)按钮类组件
Flutter 组件(三)按钮类组件
169 0
|
4天前
|
UED
Flutter之自定义路由切换动画
Flutter之自定义路由切换动画 在Flutter中,我们可以通过Navigator来实现路由管理,包括路由的跳转和返回等。默认情况下,Flutter提供了一些简单的路由切换动画,但是有时候我们需要自定义一些特殊的动画效果来提高用户体验。本文将介绍如何在Flutter中实现自定义的路由切换动画。
|
4天前
|
开发框架 Dart 容器
Flutter 自定义渐变按钮 GradientButton
Flutter 自定义渐变按钮 GradientButton Flutter 是一种流行的跨平台移动应用开发框架。Flutter 提供了许多内置的小部件,但有时您可能需要创建自己的小部件以满足特定的需求。这个文档将介绍如何创建一个自定义渐变按钮小部件 GradientButton。
|
4天前
|
开发框架
Flutter 工程化框架选择——搞定 Flutter 动画
Flutter 工程化框架选择——搞定 Flutter 动画 Flutter 是 Google 推出的跨平台移动应用开发框架,它具有快速开发、高性能、美观等优点。但是,在实际开发中,为了更好地维护和扩展代码,我们需要选择一个合适的工程化框架来协助我们进行开发。本文将介绍几种常用的 Flutter 工程化框架,并重点介绍一个搞定 Flutter 动画的方法。