Flutter TabBarView 嵌套TabBarView,

2020-04-19  本文已影响0人  十默_

需求

内容式的App 会有很多内容显示,需要很多卡片,TabBarView 嵌套是很正常的,很多时候产品会要求嵌套的TabBarView 滚动到边缘时候,要和外面的TabBarView流畅地联动。

TabBarView 基本流程

我们先来看TabBarView的基本流程:


image.png

TabBarView 实际上是一个PageView
TabBarView 捕捉PageView 滑动:更新tabController.offset, 通知indicator 位置变化; 更新tabController.index 修改TabBarView 显示的 Tab。
PageView 是Scrollable + Viewport
PageView 通过Scrollable 滑动,进行更改通知onPageChanged;

那么PageView 是怎么实现页面滑动的呢?
Scrollable 内部 创建一个ScrollPosition, ScrollPosition 绑定到ScrollController, 当进行手势的时候,比如滑动,拖拽等, 将手势产生的变化通过修改ScrollPosition同步给ScrollController, 同时发送ScrollNotification。

所以,关键在于,手势修改ScrollPosition, 实现视图滚动。 详细可以阅读flutter/src/gestures/drag.dart.

那么实现嵌套的TabBarView 联动,需要:

实现要点

效果图

image.png

使用

Github: https://github.com/wilin52/union_tabs

1.Install

dependencies:
  union_tabs: ^1.0.0+4

2.Import

import 'package:union_tabs/union_tabs.dart';

3.Usage

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
          bottom: TabBar(
              controller: _controller,
              tabs: tabsText.map((it) => Tab(text: it)).toList()),
        ),
        body: UnionOuterTabBarView( /// outerTabBarView
          controller: _controller,
          children: _createTabContent(),
        ));
  }

  List<Widget> _createTabContent() {
    List<Widget> tabContent = List();
    tabContent.add(Center(child: Text(tabsText[0])));
    final child = Column(
      children: <Widget>[
        TabBar(
            labelColor: Colors.black,
            unselectedLabelColor: Colors.black45,
            controller: _childController,
            tabs: secondTabsText.map((it) => Tab(text: it)).toList()),
        Expanded(
          child: UnionInnerTabBarView( /// innerTabBarView
              controller: _childController,
              children:
                  secondTabsText.map((it) => Center(child: Text(it))).toList()),
        )
      ],
    );
    tabContent.add(child);
    tabContent.add(Center(child: Text(tabsText[2])));
    return tabContent;
  }
上一篇 下一篇

猜你喜欢

热点阅读