#flutter
#flutter
Вопрос:
Макет работает так, как хотелось, за исключением этого:
Когда я прокручиваю одну страницу, вторая страница тоже прокручивается. Не так много, но достаточно, чтобы скрыть первый элемент.
Я мог бы предположить, что это как-то связано с NestedScrollView, но я не знаю, как поступить дальше.
import 'package:flutter/material.dart';
main(){
runApp(new MaterialApp(
home: new MyHomePage(),
));
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new DefaultTabController(
length: 2,
child: new Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
new SliverAppBar(
title: const Text('Tabs and scrolling'),
forceElevated: innerBoxIsScrolled,
pinned: true,
floating: true,
bottom: new TabBar(
tabs: <Tab>[
new Tab(text: 'Page 1'),
new Tab(text: 'Page 2'),
],
),
),
];
},
body: new TabBarView(
children: <Widget>[
_list(),
_list(),
],
),
),
),
);
}
Widget _list(){
return ListView.builder(
padding: EdgeInsets.zero,
itemCount: 250,
itemBuilder: (context, index){
return Container(
color: Colors.grey[200].withOpacity((index % 2).toDouble()),
child: ListTile(
title: Text(index.toString()),
),
);
}
);
}
}
Ответ №1:
Чтобы иметь возможность прокручивать два ListViews, не влияя друг на друга, они должны иметь определенные контроллеры.
Чтобы ListViews сохраняли свое положение прокрутки при переключении вкладок, вам необходимо разместить их в виджете с AutomaticKeepAliveClientMixin.
Вот пример того, что вы можете сделать вместо вашего метода _list . Определен виджет с отслеживанием состояния, который возвращает ваши списки, используя оба контроллера и AutomaticKeepAliveClientMixin:
class ItemList extends StatefulWidget {
@override
_ItemListState createState() => _ItemListState();
}
class _ItemListState extends State<ItemList> with AutomaticKeepAliveClientMixin{
ScrollController _scrollController = ScrollController();
@override
Widget build(BuildContext context) {
super.build(context);
return ListView.builder(
controller: _scrollController,
padding: EdgeInsets.zero,
itemCount: 250,
itemBuilder: (context, index){
return Container(
color: Colors.grey[200].withOpacity((index % 2).toDouble()),
child: ListTile(
title: Text(index.toString()),
),
);
}
);
}
@override
bool get wantKeepAlive => true;
}
Вы можете просто вызвать его обычным способом, как любой другой виджет в вашем TabBarView:
TabBarView(
children: <Widget>[
ItemList(),
ItemList(),
],
),