Flutter 滚动距离来设置TabBar的位置,点击TabBar滚动的到指定的位置

简介: Flutter 滚动距离来设置TabBar的位置,点击TabBar滚动的到指定的位置
效果gif

定义属性
    final tabBarHeight = useRef(42.0);
    final items = useRef(['产品详情', '购买须知', '服务评价']
        .map((e) => Tab(
              height: 40,
              text: e,
            ))
        .toList());
    final tabC = useTabController(initialLength: items.value.length);
    final scroller = useScrollController();

    final isTabClicked = useRef(false);

    final keys = useRef([
      GlobalKey(debugLabel: 'tab1'),
      GlobalKey(debugLabel: 'tab2'),
      GlobalKey(debugLabel: 'tab3'),
    ]);
定义监听
useEffect(() {
      void tabCL() {
        if (tabC.indexIsChanging) {
          isTabClicked.value = true;
          final keyRenderObject = keys.value[tabC.index].currentContext
              ?.findAncestorRenderObjectOfType();
          scroller.position
              .ensureVisible(keyRenderObject!,
                  duration: const Duration(milliseconds: 300),
                  curve: Curves.easeIn)
              .then((value) {
            isTabClicked.value = false;
          });
        }
      }

      void scrL() {
        if (isTabClicked.value) return;
        int i = 0;
        for (; i < keys.value.length; i++) {
          final keyRenderObject =
              keys.value[i].currentContext?.findAncestorRenderObjectOfType();
          if (keyRenderObject != null) {
            final offsetY =
                (keyRenderObject.parentData as SliverPhysicalParentData)
                    .paintOffset
                    .dy;
            if (offsetY > tabBarHeight.value) {
              break;
            }
          }
        }
        tabC.index = i > 0 ? i - 1 : 0;
      }

      tabC.addListener(tabCL);
      scroller.addListener(scrL);
      return () {
        tabC.removeListener(tabCL);
        scroller.removeListener(scrL);
        tabC.dispose();
        scroller.dispose();
      };
    }, [3]);
每个组件设置Key
CustomScrollView(
        controller: scroller,
        slivers: [
          SliverAppBar(
            backgroundColor: Colors.transparent,
            pinned: true,
            toolbarHeight: 0,
            expandedHeight: 380,
            flexibleSpace: const FlexibleSpaceBar(
              background: HeaderProductDetail(),
            ),
            bottom: PreferredSize(
              preferredSize: Size.fromHeight(tabBarHeight.value),
              child: Container(
                color: Colors.white,
                child: TabBar(
                  tabs: items.value,
                  controller: tabC,
                  unselectedLabelColor: Colors.grey,
                  indicator: context.extensions.underlineTabIndicator,
                ),
              ),
            ),
          ),
          SliverToBoxAdapter(
            child: Container(
              key: keys.value[0],
              height: Screens.height,
              width: double.infinity,
              color: Colors.red,
              child: Text("==============="),
            ),
          ),
          SliverToBoxAdapter(
            child: Container(
              key: keys.value[1],
              height: Screens.height,
              width: double.infinity,
              color: Colors.yellow,
              child: Text("==============="),
            ),
          ),
          SliverToBoxAdapter(
            child: Container(
              key: keys.value[2],
              height: Screens.height,
              width: double.infinity,
              color: Colors.blue,
              child: Text("==============="),
            ),
          )
        ],
      )


参考

Flutter TabBar实现描点滚动绑定

源码 感觉有用的话,star一下

github地址

相关文章
|
6月前
|
数据库 容器
Flutter笔记:滚动之-无限滚动与动态加载的实现
Flutter笔记:滚动之-无限滚动与动态加载的实现
280 0
|
存储 数据库 索引
Flutter笔记:滚动之-无限滚动与动态加载的实现(GetX简单状态管理版)
本文介绍Flutter中如何实无线滚动(基于GetX简单状态管理而非有状态组件)
134 0
|
13天前
|
UED 开发者 容器
Flutter&鸿蒙next 的 Sliver 实现自定义滚动效果
Flutter 提供了强大的滚动组件,如 ListView 和 GridView,但当需要更复杂的滚动效果时,Sliver 组件是一个强大的工具。本文介绍了如何使用 Sliver 实现自定义滚动效果,包括 SliverAppBar、SliverList 等常用组件的使用方法,以及通过 CustomScrollView 组合多个 Sliver 组件实现复杂布局的示例。通过具体代码示例,展示了如何实现带有可伸缩 AppBar 和可滚动列表的页面。
74 1
|
4月前
flutter 导航组件 AppBar (含顶部选项卡TabBar,抽屉菜单 drawer ,自定义导航图标)
flutter 导航组件 AppBar (含顶部选项卡TabBar,抽屉菜单 drawer ,自定义导航图标)
66 1
|
4月前
|
UED
Flutter-无限循环滚动标签
Flutter-无限循环滚动标签
78 0
|
4月前
|
容器
Flutter Container设置 width 无效
Flutter Container设置 width 无效
|
6月前
|
前端开发 UED 开发者
【Flutter前端技术开发专栏】Flutter中的列表与滚动视图优化
【4月更文挑战第30天】Flutter开发中,优化列表和滚动视图至关重要。本文介绍了几种优化方法:1) 使用`ListView.builder`和`GridView.builder`实现懒加载;2) 复用子组件以减少实例创建;3) 利用`CustomScrollView`和`Slivers`提升滚动性能;4) 通过`NotificationListener`监听滚动事件;5) 使用`KeepAlive`保持列表项状态。掌握这些技巧能提升应用性能和用户体验。
102 1
【Flutter前端技术开发专栏】Flutter中的列表与滚动视图优化
|
5月前
|
容器
flutter GestureDetector 点击空白区域无反应解决办法
flutter GestureDetector 点击空白区域无反应解决办法
134 0
|
6月前
|
存储 缓存 监控
【Flutter前端技术开发专栏】Flutter中的列表滚动性能优化
【4月更文挑战第30天】本文探讨了Flutter中优化列表滚动性能的策略。建议使用`ListView.builder`以节省内存,避免一次性渲染所有列表项。为防止列表项重建,可使用`UniqueKey`或`ObjectKey`。缓存已渲染项、减少不必要的重绘和异步加载大数据集也是关键。此外,选择轻量级组件,如`StatelessWidget`,并利用Flutter DevTools监控性能以识别和解决瓶颈。持续测试和调整以提升用户体验。
203 0
【Flutter前端技术开发专栏】Flutter中的列表滚动性能优化
|
6月前
|
前端开发 数据处理
【Flutter 前端技术开发专栏】Flutter 中的滚动性能优化与无限列表实现
【4月更文挑战第30天】本文探讨了 Flutter 中的滚动性能优化和无限列表实现。关键点包括:1) 滚动性能直接影响用户满意度,优化可提升响应速度;2) 影响因素有布局复杂度、频繁重绘和数据处理;3) 优化措施包括懒加载、简化布局、减少不必要的重绘和高效处理数据;4) 无限列表通过监听滚动位置,动态加载新数据;5) 实现时注意加载策略、数据处理效率和内存管理。案例分析和总结强调了优化在实际开发中的重要性。
122 0
【Flutter 前端技术开发专栏】Flutter 中的滚动性能优化与无限列表实现