Flutter实现动画卡片式Tab导航

栏目: IOS · 发布时间: 7年前

内容简介:本人接触Flutter不到一个月,深深感受到了这个平台的威力,于是不断学习,Flutter官方Example中的其中的animation内容,展示的是一个官方展示了一个非常好的开源示例,我改造了一下,也不敢独自享用,现在分享给大家,欢迎大家多多交流

本人接触Flutter不到一个月,深深感受到了这个平台的威力,于是不断学习,Flutter官方Example中的 flutter_gallery 有一个非常好看的动画卡片式的Tab导航,很好的展示了Flutter各个widget的功能

其中的animation内容,展示的是一个 带有动画和拖拽功能的 可展开的 卡片式Tab导航,非常漂亮,但是其实现没有抽象出一个可供第三方使用的Widget出来,而且其页面内容的定制性不够友好,滑动的时候也有bug,我在他的基础上进行了优化

官方展示了一个非常好的开源示例,我改造了一下,也不敢独自享用,现在分享给大家,欢迎大家多多交流

外观

Flutter实现动画卡片式Tab导航

实现

这里是我的代码: GitHub/Realank

想使用这个控件非常简单,首先定义页面数据:

const Color _mariner = const Color(0xFF3B5F8F);
const Color _mediumPurple = const Color(0xFF8266D4);
const Color _tomato = const Color(0xFFF95B57);
const Color _mySin = const Color(0xFFF3A646);

List<CardSection> allSections = <CardSection>[
  new CardSection(
      title: 'First Page',
      leftColor: _mediumPurple,
      rightColor: _mariner,
      contentWidget: Center(child: new Text('第一页'))),
  new CardSection(
      title: 'Second Page',
      leftColor: _mariner,
      rightColor: _mySin,
      contentWidget: Center(child: new Text('第二页'))),
  new CardSection(
      title: 'Third Page',
      leftColor: _mySin,
      rightColor: _tomato,
      contentWidget: Center(child: new Text('第三页'))),
  new CardSection(
      title: 'Forth Page',
      leftColor: _tomato,
      rightColor: Colors.blue,
      contentWidget: Center(child: new Text('第四页'))),
  new CardSection(
      title: 'Fifth Page',
      leftColor: Colors.blue,
      rightColor: _mediumPurple,
      contentWidget: Center(child: new Text('第五页'))),
];
复制代码

然后创建这个控件:

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      home: new Scaffold(
        body: Center(
          child: new AnimateTabNavigation(
            sectionList: allSections,
          ),
        ),
      ),
    );
  }
}
复制代码

大功告成

原理

知其然还要知其所以然,下面来说说这个控件的实现原理

首先,在sections.dart里定义了数据结构:

class CardSection {
  CardSection({this.title, this.leftColor, this.rightColor, this.contentWidget});

  final String title;
  final Color leftColor;
  final Color rightColor;
  final Widget contentWidget;

  @override
  bool operator ==(Object other) {
    if (other is! CardSection) return false;
    final CardSection otherSection = other;
    return title == otherSection.title;
  }

  @override
  int get hashCode => title.hashCode;
}

复制代码

它定义了其中一个卡片的标题,左边颜色和右边颜色(为了显示过渡颜色效果),以及子控件(这个是我改进的,这样可以别人使用的时候随意添加控件)

然后在widgets.dart中定义了几个widget:

  • SectionCard : 标题卡片
  • SectionTitle : 标题
  • SectionIndicator : 标题下的装饰线

最后在cardNavigation.dart中就是布局这些内容啦,这里面代码很复杂,其思路倒是不难:

  1. 定义全屏展示tab的高度maxHeight,以及打开tab后,tab显示在顶部的高度minHeight
  2. 在用户拖动tab卡片的时候,根据卡片的位置于minHeight和maxHeight的比例,计算出动画进度(0.0-1.0)
  3. 在_AllSectionsLayout中,定义了全屏显示tab时,卡片的columnCardRect,以及打开tab后,tab显示在顶部时候的rowCardRectt
  4. 计算出这两个rect在动画进度0-1过程中的中间态的rect尺寸,赋值给每一个卡片,这样卡片就有中间状态的外观了。
  5. 当用户点击了tab区域,就会触发_maybeScroll方法,这个方法判断当前的tab是全屏的还是打开后的
  6. 当tab是全屏的,就展开对应的tab页
  7. 当tab已经是打开的,就判断点击的位置,在tab栏的左侧,就往左翻页,反之亦然。

以上所述就是小编给大家介绍的《Flutter实现动画卡片式Tab导航》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Machine Learning in Action

Machine Learning in Action

Peter Harrington / Manning Publications / 2012-4-19 / GBP 29.99

It's been said that data is the new "dirt"—the raw material from which and on which you build the structures of the modern world. And like dirt, data can seem like a limitless, undifferentiated mass. ......一起来看看 《Machine Learning in Action》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具