Flutter 扩展的联动Tabs

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

内容简介:Flutter里面使用TabBar和TabBarView的时候。如果是二级TabBar,产品说了一个需求:二级TabBar需要是那种联动的,就是说下面一层的TabBar滑不动了,就滑动上一层的TabBar,不知道这个效果在安卓/IOS里面叫什么,搜了下网上也没看到。那么我们打开flutter\packages\flutter\lib\src\material\tabs.dart,开始魔改。1.首先我们需要获取到上一层的TabBarView.

Flutter里面使用TabBar和TabBarView的时候。如果是二级TabBar,产品说了一个需求:二级TabBar需要是那种联动的,就是说下面一层的TabBar滑不动了,就滑动上一层的TabBar,不知道这个效果在安卓/IOS里面叫什么,搜了下网上也没看到。

Flutter 扩展的联动Tabs

目录

  • TabBar色卡指示器ColorTabIndicator

  • 控制缓存页数CacheExtent

Flutter 扩展的联动Tabs

联动的TabBarView

那么我们打开flutter\packages\flutter\lib\src\material\tabs.dart,开始魔改。

1.首先我们需要获取到上一层的TabBarView.

Widget build(BuildContext context) {
    if (widget.linkWithAncestor) {
      _ancestor =
          context.ancestorStateOfType(TypeMatcher<_ExtendedTabBarViewState>());
    }
复制代码
  1. 不能滑动的时候我们能拿到OverscrollNotification,看这个之前强烈建议去看一下NotificationListener,这个是个好东西,能监听各种通知。

我们来到_handleScrollNotification这个方法添加判断 notification is OverscrollNotification

if (notification is OverscrollNotification && _ancestor != null) {
      var overscrollNotification = notification as OverscrollNotification;
      if (_canlinkeWithAncestorScroll(overscrollNotification.overscroll < 0)) {
        _ancestor._pageController.position.moveTo(
            _ancestor._pageController.offset +
                overscrollNotification.overscroll);
      }
    }
复制代码

并且通过_canlinkeWithAncestorScroll方法判断上一层TabBarView是否能滑动

bool _canlinkeWithAncestorScroll(bool onLeftEdge) {
    //return false;
    if (_ancestor == null) return false;
    return (onLeftEdge &&
            _ancestor._pageController.offset !=
                _ancestor._pageController.position.minScrollExtent) ||
        ((!onLeftEdge &&
            _ancestor._pageController.offset !=
                _ancestor._pageController.position.maxScrollExtent));
  }
复制代码

3.将上层TabBarView的_pageController改变为offset+拖动overscroll的。这样效果就完成了。

_ancestor._pageController.position.moveTo(
            _ancestor._pageController.offset +
                overscrollNotification.overscroll);
复制代码

4.如果上层可以滑动,我们需要去掉overscroll的阻尼效果。 首先在增加对OverscrollIndicatorNotification的监听

return NotificationListener<ScrollNotification>(
      onNotification: _handleScrollNotification,
      child: NotificationListener<OverscrollIndicatorNotification>(
        onNotification: _handleGlowNotification,
        child: ExtendedPageView(
          controller: _pageController,
          physics: widget.physics == null
              ? _kTabBarViewPhysics
              : _kTabBarViewPhysics.applyTo(widget.physics),
          children: _children,
        ),
      ),
    );
复制代码

判断是否上层TabBarView能否滑动

bool _handleGlowNotification(OverscrollIndicatorNotification notification) {
    debugPrint("${notification.depth}++++ ${_ancestor != null}");
    if (notification.depth == 0 &&
        _canlinkeWithAncestorScroll(notification.leading)) {
      notification.disallowGlow();
      return true;
    }
    return false;
  }
复制代码

产品要的联动效果就这样搞定了。。是不是很简单。。多看源码还是有很多好处的。。

TabBar色卡指示器ColorTabIndicator

这个是随手送的功能。。( ╯□╰ )就是TabBar指示器为一个色块,代码没啥好说的

class ColorTabIndicator extends Decoration {
  ColorTabIndicator(this.color);

  /// The color and weight of the horizontal line drawn below the selected tab.
  final Color color;

  @override
  Decoration lerpFrom(Decoration a, double t) {
    return super.lerpFrom(a, t);
  }

  @override
  Decoration lerpTo(Decoration b, double t) {
    return super.lerpTo(b, t);
  }

  @override
  _ColorPainter createBoxPainter([VoidCallback onChanged]) {
    return _ColorPainter(this, onChanged);
  }
}

class _ColorPainter extends BoxPainter {
  _ColorPainter(this.decoration, VoidCallback onChanged)
      : assert(decoration != null),
        super(onChanged);

  final ColorTabIndicator decoration;

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    assert(configuration != null);
    assert(configuration.size != null);
    final Rect rect = offset & configuration.size;
    final Paint paint = Paint();
    paint.color = decoration.color;
    canvas.drawRect(rect, paint);
  }
}
复制代码

控制缓存页数CacheExtent

/// cache page count
  /// default is 0.
  /// if cacheExtent is 1, it has two pages in cache
  /// null is infinity, it will cache all pages
  final int cacheExtent;
复制代码

控制TabBarView缓存页面的个数,通过重写了PageView中的Viewport的cacheExtent值来实现。

ExtendedPageView 的build方法中,增加了对Viewport的cacheExtend的设置。

child: Scrollable(
        axisDirection: axisDirection,
        controller: widget.controller,
        physics: physics,
        viewportBuilder: (BuildContext context, ViewportOffset position) {
          if (widget.cacheExtent > 0) {
            return LayoutBuilder(
                builder: (BuildContext context, BoxConstraints constraints) {
              return Viewport(
                cacheExtent: widget.cacheExtent * constraints.maxWidth,
                axisDirection: axisDirection,
                offset: position,
                slivers: <Widget>[
                  SliverFillViewport(
                      viewportFraction: widget.controller.viewportFraction,
                      delegate: widget.childrenDelegate),
                ],
              );
            });
          } else {
            return Viewport(
              cacheExtent: widget.cacheExtent == null ? double.infinity : 0.0,
              axisDirection: axisDirection,
              offset: position,
              slivers: <Widget>[
                SliverFillViewport(
                    viewportFraction: widget.controller.viewportFraction,
                    delegate: widget.childrenDelegate),
              ],
            );
          }
        },
      ),
复制代码

最后放上 Github extended_tabs ,如果你有什么不明白的地方,请告诉我。

Flutter 扩展的联动Tabs

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

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

Understanding Machine Learning

Understanding Machine Learning

Shai Shalev-Shwartz、Shai Ben-David / Cambridge University Press / 2014 / USD 48.51

Machine learning is one of the fastest growing areas of computer science, with far-reaching applications. The aim of this textbook is to introduce machine learning, and the algorithmic paradigms it of......一起来看看 《Understanding Machine Learning》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具