Flutter tabsView和NestedScrollView滚动问题

我有一个“ NestedScrollView”,其中包含多个“

TabView”小部件,并且每个选项卡都有一个列表生成器。问题是,当我滚动浏览特定选项卡中的一个列表时,滚动位置会影响其他选项卡中的所有其他列表。

即使我确实将“ ScrollController”添加到每个listview(在选项卡中),选项卡滚动中的listBuilder也与“

NestedScrollView”分开,这是示例代码:

import 'package:flutter/material.dart';

void main() => runApp(

MaterialApp(

home: MyApp()

,

)

);

class MyApp extends StatefulWidget{

MyAppState createState() => MyAppState();

}

class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {

TabController tabController;

Widget _tabBarView;

@override

void initState() {

super.initState();

tabController = TabController(length: 2, vsync: this,);

_tabBarView = TabBarView(

children: [

DemoTab(),

DemoTab(),

]);

}

@override

Widget build(BuildContext context) {

return Scaffold(

body: NestedScrollView(

controller: ScrollController(keepScrollOffset: true),

headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {

return <Widget>[

SliverList(

delegate: SliverChildListDelegate(

[

Container(height: 300, color: Colors.blue)

]

),

),

];

},

body: DefaultTabController(

length: 2,

child: Column(

children: <Widget>[

Expanded(

child: Container(

child: _tabBarView

),

),

],

),

)

),

);

}

}

class DemoTab extends StatefulWidget{

DemoTabState createState() => DemoTabState();

}

class DemoTabState extends State<DemoTab> with AutomaticKeepAliveClientMixin<DemoTab>{

@override

// TODO: implement wantKeepAlive

bool get wantKeepAlive => true;

@override

Widget build(BuildContext context) {

return ListView.builder(

key: UniqueKey(),

itemBuilder: (b, i) {

return Container(

height: 50,

color: Colors.green,

margin: EdgeInsets.only(bottom: 3),

child: Text(i.toString(),),

);

}, itemCount: 30,) ;

}

}

回答:

3天后,我发现这是解决此问题的最佳方法,但仍需要更多改进,因为sliver标头扩展和收缩太快,您可以改进代码,并与我们分享

import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(

home: MyApp(),

));

class MyApp extends StatefulWidget {

MyAppState createState() => MyAppState();

}

class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {

TabController tabController;

Widget _tabBarView;

var scrollController = ScrollController();

@override

void initState() {

super.initState();

tabController = TabController(

length: 2,

vsync: this,

);

_tabBarView = TabBarView(children: [

DemoTab(parentController : scrollController),

DemoTab(parentController : scrollController),

]);

}

@override

Widget build(BuildContext context) {

return Scaffold(

body: NestedScrollView(

controller: scrollController,

physics: ScrollPhysics(parent: PageScrollPhysics()),

headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {

return <Widget>[

SliverList(

delegate: SliverChildListDelegate(

[Container(height: 300, color: Colors.blue)]),

),

];

},

body: DefaultTabController(

length: 2,

child: Column(

children: <Widget>[

Container(

child: TabBar(labelColor: Colors.grey, tabs: [

Tab(

text: 'One',

),

Tab(

text: 'two',

)

]),

),

Expanded(

child: Container(child: _tabBarView),

),

],

),

)),

);

}

}

class DemoTab extends StatefulWidget {

DemoTab({

this.parentController

});

final ScrollController parentController;

DemoTabState createState() => DemoTabState();

}

class DemoTabState extends State<DemoTab>

with AutomaticKeepAliveClientMixin<DemoTab> {

@override

// TODO: implement wantKeepAlive

bool get wantKeepAlive => true;

ScrollController _scrollController;

ScrollPhysics ph;

@override

void initState() {

super.initState();

_scrollController = ScrollController();

_scrollController.addListener((){

var innerPos = _scrollController.position.pixels;

var maxOuterPos = widget.parentController.position.maxScrollExtent;

var currentOutPos = widget.parentController.position.pixels;

if(innerPos >= 0 && currentOutPos < maxOuterPos) {

//print("parent pos " + currentOutPos.toString() + "max parent pos " + maxOuterPos.toString());

widget.parentController.position.jumpTo(innerPos+currentOutPos);

}else{

var currenParentPos = innerPos + currentOutPos;

widget.parentController.position.jumpTo(currenParentPos);

}

});

widget.parentController.addListener((){

var currentOutPos = widget.parentController.position.pixels;

if(currentOutPos <= 0) {

_scrollController.position.jumpTo(0);

}

});

}

@override

Widget build(BuildContext context) {

return ListView.builder(

key: UniqueKey(),

controller: _scrollController,

itemBuilder: (b, i) {

return Container(

height: 50,

color: Colors.green,

margin: EdgeInsets.only(bottom: 3),

child: Text(

i.toString(),

),

);

},

itemCount: 30,

);

}

}

以上是 Flutter tabsView和NestedScrollView滚动问题 的全部内容, 来源链接: utcz.com/qa/433599.html

回到顶部