Flutter 如何在ListView中放置键以保持页面更改状态
我正在尝试建立一个用户可以滚动浏览的帖子流(想想twitter或instagram类型的帖子)。当他们滚动时,他们可以单击其中一篇文章并导航到新页面。当它们从该页面返回时,我希望它们保持在与以前在ListView中的位置相同的位置 问题 我目前无法阻止流小部件重建并返回滚动位置。我知道解决这一问题的方法之一是包含一个密钥;但是,我尝试在ListView.builder中包含该键,但没有成功 问题 我应该把钥匙放在哪里?我使用的钥匙类型正确吗Flutter 如何在ListView中放置键以保持页面更改状态,flutter,flutter-layout,Flutter,Flutter Layout,我正在尝试建立一个用户可以滚动浏览的帖子流(想想twitter或instagram类型的帖子)。当他们滚动时,他们可以单击其中一篇文章并导航到新页面。当它们从该页面返回时,我希望它们保持在与以前在ListView中的位置相同的位置 问题 我目前无法阻止流小部件重建并返回滚动位置。我知道解决这一问题的方法之一是包含一个密钥;但是,我尝试在ListView.builder中包含该键,但没有成功 问题 我应该把钥匙放在哪里?我使用的钥匙类型正确吗 类流扩展StatefulWidget{ 流({Key
类流扩展StatefulWidget{
流({Key-Key,this.user}):超级(Key:Key);
最终用户;
@凌驾
_StreamState createState()=>new\u StreamState(
用户:用户
);
}
类_StreamState扩展了状态{
_StreamState({this.user});
最终用户;
Firestore _Firestore=Firestore.instance;
列表_posts=[];
bool_loadingPosts=真;
每页整数=30;
文档快照_lastPosts;
ScrollController_ScrollController=ScrollController();
bool_gettingMorePosts=false;
bool\u morePostsAvailable=true;
_getPosts()异步{
查询q=\u firestore
.collection(“posts”)
.document(user.user\u id)
.collection(“posts”)
.orderBy(“时间公告”,降序:true)
.限制(每页);
设置状态(){
_loadingPosts=true;
});
QuerySnapshot QuerySnapshot=wait q.getDocuments();
_posts=querySnapshot.documents;
如果(_posts.length==0){
设置状态(){
_装货柱=假;
});
}
否则{
_lastPosts=querySnapshot.documents[querySnapshot.documents.length-1];
设置状态(){
_装货柱=假;
});
}
}
_getMorePosts()异步{
if(_morespostsavailable==false){
回来
}
if(_gettingMorePosts==true){
回来
}
如果(_posts.length==0){
回来
}
_gettingMorePosts=true;
查询q=\u firestore
.collection(“posts”)
.document(user.user\u id)
.collection(“posts”)
.orderBy(“时间公告”,降序:true)
.startAfter([\u lastPosts.data['timePosted']])。限制(\u每页);
QuerySnapshot QuerySnapshot=wait q.getDocuments();
if(querySnapshot.documents.length==0){
_morePostsAvailable=false;
}
如果(querySnapshot.documents.length>0){
_lastPosts=querySnapshot.documents[querySnapshot.documents.length-1];
}
_posts.addAll(querySnapshot.documents);
setState((){});
_gettingMorePosts=false;
}
@凌驾
void initState(){
super.initState();
_getPosts();
_scrollController.addListener((){
double maxScroll=\u scrollController.position.maxScrollExtent;
双currentScroll=\u scrollController.position.pixels;
double delta=MediaQuery.of(context).size.height*0.25;
如果(maxScroll-currentScroll<增量){
_getMorePosts();
}
});
}
@凌驾
小部件构建(构建上下文){
返回列(
儿童:[
新扩展(
子项:_loadingPosts==true
?容器(
儿童:中心(
子项:文本(“”),
),
)
:容器(
儿童:中心(
子项:_posts.length==0
?中心(
子项:文本(“跟随朋友”,样式:TextStyle(fontSize:15),),
)
:ListView.builder(
key:widget.key,
控制器:\ u滚动控制器,
itemCount:_posts.length,
itemBuilder:(BuildContext ctx,int索引){
返回新部件(
//用于在此处构建post小部件的参数
);
}),
),
),
),
],
);
}
这类关键功能:
key: PageStorageKey('Your Key Name'),
这类关键工作:
key: PageStorageKey('Your Key Name'),
简短回答:
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
key: PageStorageKey("any_text_here"), // this is the key you need
itemCount: 50,
itemBuilder: (_, i) {
return ListTile(
title: Text("Item ${i}"),
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => DetailPage(index: i))),
);
},
),
);
}
}
class DetailPage extends StatefulWidget {
final int index;
const DetailPage({Key key, this.index}) : super(key: key);
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(
"You clicked ${widget.index}",
style: Theme.of(context).textTheme.headline,
),
),
);
}
}
您需要提供ListView.builder
的密钥,如下所示:
ListView.builder(
key: PageStorageKey("any_text_here"),
// ...
)
长答案: 您可以看到,当您从屏幕2返回到屏幕1时,项目30保留在顶部
很抱歉,由于您所使用的变量的可用性有限,很难重现您的代码。我创建了一个简单的示例来演示您所寻找的内容 完整代码:
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
key: PageStorageKey("any_text_here"), // this is the key you need
itemCount: 50,
itemBuilder: (_, i) {
return ListTile(
title: Text("Item ${i}"),
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => DetailPage(index: i))),
);
},
),
);
}
}
class DetailPage extends StatefulWidget {
final int index;
const DetailPage({Key key, this.index}) : super(key: key);
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(
"You clicked ${widget.index}",
style: Theme.of(context).textTheme.headline,
),
),
);
}
}
void main()=>runApp(MaterialApp(home:HomePage());
类主页扩展了StatefulWidget{
@凌驾
_HomePageState createState()=>\u HomePageState();
}
类_HomePageState扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(),
正文:ListView.builder(
key:PageStorageKey(“此处的任意文本”),//这是您需要的密钥
物品计数:50,
itemBuilder:(u,i){
返回列表块(
标题:文本(“项目${i}”),
onTap:()=>Navigator.push(上下文,materialpage(生成器:()=>DetailPage(索引:i)),
);
},
),
);
}
}
类DetailPage扩展StatefulWidget{
最终整数指数;
constdetailpage({Key,this.index}):super(Key:Key);
@凌驾
_DetailPageState createState()=>\u DetailPageState();
}
类_DetailPageState扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(),
正文:中(
子:文本(
“您单击了${widget.index}”,
风格:Theme.of(context).textTheme.headline,
),
),
);
}
}
简短回答:
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
key: PageStorageKey("any_text_here"), // this is the key you need
itemCount: 50,
itemBuilder: (_, i) {
return ListTile(
title: Text("Item ${i}"),
onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => DetailPage(index: i))),
);
},
),
);
}
}
class DetailPage extends StatefulWidget {
final int index;
const DetailPage({Key key, this.index}) : super(key: key);
@override
_DetailPageState createState() => _DetailPageState();
}
class _DetailPageState extends State<DetailPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(
"You clicked ${widget.index}",
style: Theme.of(context).textTheme.headline,
),
),
);
}
}
您需要像这样提供ListView.builder
的密钥