如何将数据从导航器弹出页面传递到前一页,在该页中使用数据的小部件内的ListView.builder。
如何将数据从导航器弹出页面传递到前一页,在该页中使用数据的小部件内的ListView.builder。
如标题所述。如何将数据返回到使用数据来列出小部件的上一页。
我已经阅读了这篇文章Flutter Back button with return data或其他类似的文章。代码完美运行。但是,如果我想将返回的数据用于列表中的小部件,就会出现问题。
请注意,我只想更新一个ListWidget,我不想像这篇文章中的解决方案Flutter: Refresh on Navigator pop or go back一样刷新整个HomePage的状态。
这里有一个简单的代码示例,代表了我所面临的问题。
(请参考下面的ListWidget类和SecondPage类)
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home'),
),
body: Center(
child: ListView.builder(
itemCount: 4,
itemBuilder: (_, index){
return ListWidget(number: index+1);
},
)
),
);
}
}
class ListWidget extends StatelessWidget{
ListWidget({@required this.number});
final int? number;
String? statusOpen;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () async {
statusOpen = await Navigator.of(context, rootNavigator: true)
.push(
MaterialPageRoute(
builder: (BuildContext context) => SecondPage(),
),
);
},
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(20),
color: Colors.amber,
child: Text(statusOpen != null ? '$number $statusOpen' : '$number Unopened'),
//
// 我希望在用户从SecondPage返回时将文本更改为'已打开'
//
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: RaisedButton(
onPressed: () {
Navigator.pop(context, '已打开');
// 将'已打开'返回给等待的statusOpen变量
},
child: Text('返回'),
),
),
);
}
}
是否有解决此问题的方法?
问题原因:在上一个页面中,通过导航器跳转到下一个页面,并且在下一个页面中修改了数据。但是当从下一个页面返回到上一个页面时,上一个页面没有更新这些修改后的数据。
解决方法:在从下一个页面返回到上一个页面时,调用setState方法来更新上一个页面中的数据。
具体代码如下:
onTap: () async {
statusOpen = await Navigator.of(context, rootNavigator: true)
.push(
MaterialPageRoute(
builder: (BuildContext context) => SecondPage(),
),
).then((value) async {
setState(() {});
});
},
问题出现的原因是在导航器(Navigator)中从弹出的页面返回到上一个页面时,无法将数据传递回上一个页面中的小部件(Widget),因为上一个页面的小部件是在ListView.builder中动态构建的。
解决方法是将listWidget(即ListView.builder中的小部件)定义为有状态的小部件(stateful widget),然后在返回上一个屏幕时调用setState方法。通过这种方式,只需更改单个列表元素而不是整个屏幕。
以下是示例代码:
class ListWidget extends StatefulWidget {
// ...
}
// ...
onTap: () async {
statusOpen = await Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(
builder: (BuildContext context) => SecondPage(),
),
);
setState(() {});
},
在这段代码中,将ListWidget更改为StatefulWidget,并在onTap事件中调用Navigator.push方法以导航到SecondPage页面。在SecondPage页面中,可以获取并处理所需的数据。然后,当从SecondPage返回到上一个页面时,调用setState方法以刷新ListWidget并更新列表元素。
通过使用这种方法,可以在导航器中从弹出的页面传递数据回到上一个页面,并在ListView.builder中使用该数据的小部件上进行更新。