![](/img/trans.png)
[英]Flutter FutureBuilder not updating when setState() is called
[英]How to avoid Flutter FutureBuilder with UniqueKey flickering when SetState() is called?
我有一個PageView
(父 PageView),它的每個頁面都是一個返回FutureBuilder
的StatefulWidget
。 FutureBuilder
本身也會返回一個PageView
(子 PageView)。 因為我希望父級和子PageView
都保留頁面,所以父級和子級小部件都使用AutomaticKeepAliveClientMixin
實現。
每個頁面都分配了一個UniqueKey
,因為頁面是動態的,這意味着用戶可以刪除某些頁面或添加頁面。 但是在調用SetState()
時,有兩個問題: 1 整個頁面閃爍; 2 子PageView
跳回到索引 0 處的頁面。
如果我不使用UniqueKey
,這兩個問題就會消失。 但是添加或刪除頁面后,您無法刷新頁面。
任何建議表示贊賞,謝謝!
顯示閃爍的代碼:
void main() async {
runApp(
MaterialApp(
title: 'Test',
home: Scaffold(
body: Bar(),
),
),
);
}
class Bar extends StatefulWidget {
@override
State<StatefulWidget> createState() => _BarState();
}
class _BarState extends State<Bar> {
List<Widget> pages;
final controller = PageController(initialPage: 0, keepPage: true);
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
pages = [
Center(child: PageWithFutureBuilder(key: UniqueKey())),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
PageWithFutureBuilder(key: UniqueKey()),
RaisedButton(
onPressed: () {
refresh();
},
child: new Icon(
Icons.refresh,
color: Colors.blue,
size: 30.0,
),
)
],
),
];
return PageView(
controller: controller,
children: pages,
);
}
void refresh() async {
setState(() {});
}
}
class PageWithFutureBuilder extends StatefulWidget {
PageWithFutureBuilder({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => _PageWithFutureBuilderState();
}
Future test() async {
return;
}
class _PageWithFutureBuilderState extends State<PageWithFutureBuilder> {
Future future;
@override
void initState() {
future = test();
super.initState();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: future,
builder: (ocntext, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Container(
color: Colors.black,
child: Center(child: CircularProgressIndicator()),
);
else if (snapshot.connectionState == ConnectionState.done) {
return Center(child: Text('test text'));
} else
return Container();
},
);
}
}
滑動到第二頁,然后單擊按鈕,您會看到閃爍。 至於jumping back to page at index 0
的代碼,太復雜了,就不放了,估計和閃爍的原因是一樣的。
我想我找到了正確的解決方案。 基本上是用錯了Key
造成的。 使用UniqueKey
使 Flutter 將子小部件視為不同,因此每次重建時它都會重新初始化新的子小部件。 因此閃爍並跳回索引 0 處的頁面。
不要使用UniqueKey
,而是使用值鍵。 在我的例子中,我的每個孩子父母都有一個唯一的object ID
,所以我使用Key(objectID)
作為鍵。 因此,當調用SetState()
時,flutter 將知道某些小部件可以重復使用,因為它們具有相同的鍵,因此閃爍消失並且它不會跳回到索引 0 處的頁面。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.