Flutter滚动ListView时TabBar出现抖动问题求助
Flutter TabBar滚动抖动问题修复
问题描述
AppBar中集成TabBar,TabBarView内放置ListView,滚动列表时TabBar下方会快速出现并消失一块空白区域,造成抖动错觉。已移除TabBar指示器装饰,问题仍存在,需求是让TabBar紧贴AppBar底部,无空白区域。
原代码
_appBar(){ return PreferredSize( preferredSize: Size.fromHeight(160), child: AppBar( toolbarHeight: 70, backgroundColor: Colors.white, shadowColor: Colors.black, elevation: 7, centerTitle: true, bottom: PreferredSize( preferredSize: Size.fromHeight(90.0), child: Container( padding: EdgeInsets.only(left: 10, right: 10), child: Column( children: [ Container( height: 40, width: MediaQuery.of(context).size.width - 80, decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Color.fromRGBO(243, 243, 243, 1), ), child: Center( child: Form( child: TextFormField( controller: searchController, autocorrect: false, keyboardType: TextInputType.visiblePassword, textInputAction: TextInputAction.done, decoration: InputDecoration( contentPadding: EdgeInsets.only(right: 1, left: 14, top: 14, bottom: 14), label: Text("Nome, nº de série"), labelStyle: TextStyle( fontFamily: "OpenSans", fontSize: 16, color: Color.fromRGBO(60, 60, 67, 0.6) ), prefixIcon: Icon(Icons.search), border: InputBorder.none, floatingLabelBehavior: FloatingLabelBehavior.never, ), ), ), ), ), SizedBox(height: 15), TabBar( controller: _tabController, labelPadding: EdgeInsets.only(left: 5, right: 5), indicatorColor: Theme.of(context).primaryColor, indicatorSize: TabBarIndicatorSize.label, indicatorWeight: 3.0, labelColor: Colors.black, labelStyle: TextStyle( fontSize: 16, fontFamily: "OpenSans" ), tabs: const [ Tab(text: "RASCUNHOS"), Tab(text: "EM PROCESSO"), Tab(text: "FINALIZADO"), ] ) ], ), ), ), ), ); }
抖动现象

修复方案
1. 精确计算PreferredSize高度
原代码中bottom的PreferredSize设为90,但内部元素总高度是40(搜索框) + 15(SizedBox) + 48(TabBar默认高度)= 103,高度不匹配导致布局溢出,引发抖动。修改bottom的PreferredSize为103,外层PreferredSize为70+103=173:
PreferredSize( preferredSize: Size.fromHeight(173), // 70+103 child: AppBar( toolbarHeight: 70, bottom: PreferredSize( preferredSize: Size.fromHeight(103.0), // 40+15+48 // ... 其他代码 ), ), )
2. 优化Column布局
Column默认会占用额外空间,设置mainAxisSize: MainAxisSize.min和crossAxisAlignment: CrossAxisAlignment.stretch,避免不必要的空白:
Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 搜索框组件 SizedBox(height: 15), TabBar( // ... TabBar属性 ) ], )
3. 消除TabBar底部默认间距
给TabBar设置padding: EdgeInsets.zero,移除默认的底部内边距:
TabBar( padding: EdgeInsets.zero, // ... 其他属性 )
4. 使用NestedScrollView稳定滚动联动
将AppBar和TabBarView放入NestedScrollView中,确保滚动时AppBar的布局高度稳定,避免跳动:
@override Widget build(BuildContext context) { return Scaffold( body: NestedScrollView( headerSliverBuilder: (context, innerBoxIsScrolled) => [ _appBar(), ], body: TabBarView( controller: _tabController, children: [ ListView(/* ... */), ListView(/* ... */), ListView(/* ... */), ], ), ), ); }
内容的提问来源于stack exchange,提问作者Gabi Mangili
相关产品推荐
相关产品推荐

