两个listview在NestedScrollView中同时滚动



我正面临着2个listViews同时滚动的问题:

DefaultTabController(
length: 2,
child: NestedScrollView
(

headerSliverBuilder: (context, innerBoxIsScrolled)
{
return
[
SliverAppBar(
title: Text('HOME', style: Theme.of(context).textTheme.headline5,),
floating: true,
pinned: false,
snap: true,
titleSpacing: 0.1,

bottom: TabBar(
isScrollable: true,
indicatorSize: TabBarIndicatorSize.label,
labelPadding: EdgeInsets.symmetric(horizontal: 60),
controller: tabController,


tabs: 
[
Tab(child: Text('Tab 1', style: Theme.of(context).textTheme.headline6,)),
Tab(child: Text('Tab 2', style: Theme.of(context).textTheme.headline6)),
],
),
),
];
}, //header sliver builder

body: TabBarView(
controller: tabController,
children: 
[
ListViews1, //ListView.builder
ListViews2  //ListView.builder
],
),
)
),

标签栏控制器当滑动或点击标签时收听更改。正确地返回了索引。第一个标签为0and1 for second tab

tabController = TabController(length: 2, vsync: this);
tabController.addListener(_handleTabSelection);
void _handleTabSelection() {
if(!tabController.indexIsChanging)
{
log('CALLED : ${tabController.index}');
}

}

两个类都保持存活这样滚动位置就不会丢失:

class _ListView1State extends State<ListView1> with AutomaticKeepAliveClientMixin<ListView1>{
@override
bool get wantKeepAlive => true;

class _ListView2State extends State<ListView2> with AutomaticKeepAliveClientMixin<ListView2>{
@override
bool get wantKeepAlive => true;

:当我滚动第一个列表时,第二个列表也自动滚动,反之亦然。这里有什么问题?

它们都被保持活着,它们都从主控制器读取控制器(这是由NestedScrollView创建的)当controller = nullprimary = true(这似乎是情况)。我没有办法测试它,但我可以这样做:

只需在每个状态中创建一个ScrollController,并检查它们是否独立地保留它们的值

class _ListView1State extends State<ListView1> with AutomaticKeepAliveClientMixin<ListView1>{
late final ScrollController _scrollController;
@override
void initState() {
_scrollController = ScrollController();
super.initState();
}
@override
void dispose() {
_scrollcontroller.dispose();
super.dispose();
}
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
return .....
//// pass the controller to the scroll widget you use
}
}

重复使用_ListView2State并尝试它,现在它们应该在滚动中也保留自己的状态

编辑

当tabController不显示时,读取tabController并切换到scrollController呢

class _ListView1State extends State<ListView1> with AutomaticKeepAliveClientMixin<ListView1>{
ScrollController? _scrollController;
double? _offset;
TabController tabController;
///And repeat with index tabController.index != 1 for ListView2
void setController() {
if (tabController.index != 0 && scrollController == null) {
_offset = PrimaryScrollController.of(context).controller.offset;
scrollController = ScrollController(initialScrollOffset: _offset ?? 0);
setState(() {});
} else if (tabController.index == 0 && scrollController != null) {
final primary = PrimaryScrollController.of(context).controller;
if (_offset != null && primary.offset != _offset) primary .jumpTo(_offset);
setState(() {
_offset = scrollController.offset;
scrollController = null;
});
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
final _tabController = DefaultTabController.of(context);
if (tabController != null &&_tabController != tabController) {
tabController.removeListener(setController);
}
tabController = _tabController;
tabController.addListener(setController);
}
@override
void dispose() {
_scrollcontroller?.dispose();
tabController.removeListener(setController);
super.dispose();
}
@override
bool get wantKeepAlive => true;
@override
Widget build(BuildContext context) {
return .....
//// pass the controller to the scroll widget you use
}
}

最新更新