使用 Futurebuilder 有条件地渲染小部件
Posted
技术标签:
【中文标题】使用 Futurebuilder 有条件地渲染小部件【英文标题】:Using Futurebuilder to render widgets conditionally 【发布时间】:2020-01-25 00:49:21 【问题描述】:我是 Flutter 和 Dart 的新手。所以我正在尝试在 Flutter 中构建一个简单的身份验证系统。当用户打开应用程序时,我想在他们登录时向他们显示LoginScreen
(他们以前没有登录的地方)或HomeScreen
。
loadWidget
,它返回一个Future
将确定是否存在持久数据,从而获取用户信息并显示主屏幕。 child 属性不允许我为其分配 Future,我不确定,但我想我必须为此使用 FutureBuilder 小部件?
第一次尝试
Future<Widget> loadWidget() async
SharedPreferences prefs = await SharedPreferences.getInstance();
// already logged in
String phone = prefs.getString('phoneNumber');
if (phone != null)
helper.user = await checkUser(phone); // fetch user info
return HomeScreen();
// Not logged in
else
return Login();
对于构建功能,这不起作用
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
body: loadWidget(), // This does not allow me to assign a future
)
);
第二次尝试:使用 FutureBuilder 我在这里阅读了有关 Futurebuilder how to assign future<> to widget in flutter? 的信息,它看起来像是要走的路,所以我将构建方法修改为
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
body: FutureBuilder(
future: loadWidget(),
builder: (BuildContext context, AsyncSnapshot<Widget> widget)
return widget;
,
),
),
);
但这给了我以下错误:
返回类型“AsyncSnapshot”不是定义的“Widget” 通过匿名关闭。
我怎样才能做到这一点?谢谢!
【问题讨论】:
【参考方案1】:我会将未来移到 FutureBuilder 中,然后将逻辑放入其中
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
body: FutureBuilder(
future: loadWidget(),
builder: (BuildContext context, AsyncSnapshot<Widget> sharedPreference)
String phone = sharedPreference.getString('phoneNumber');
if (phone != null)
return HomeScreen();
// Not logged in
else
return Login();
),
),
);
【讨论】:
【参考方案2】:您做得对,但问题在于 FutureBuilder 的返回对象,请参阅此代码中的 cmets:
// *NOTE: build return Widget: Widget build...
Widget build(BuildContext context)
return MaterialApp(
home: Scaffold(
body: FutureBuilder(
future: loadWidget(),
builder: (BuildContext context, AsyncSnapshot<Widget> widget)
// But 'widget' here is NOT a widget, it is an AsyncSnapshot object,
// return widget; // **is wrong**
// instead:
return widget.data;
// and better to make it like this:
//if (!widget.hasData)
// return Center(
// child: CircularProgressIndicator(),
// );
//
//return widget.data;
,
),
),
);
那是为了修复错误。关于更简洁代码的额外建议,通过使其仅返回状态(Auth 或 Not)来保持身份验证层(loadWidget)的清洁,然后在 FutureBuilder
中使用 widget.data
捕获状态,然后根据 Auth 状态进行路由从FutureBuilder
内部。
【讨论】:
这行得通。另外,谢谢你的建议,会记住的:)以上是关于使用 Futurebuilder 有条件地渲染小部件的主要内容,如果未能解决你的问题,请参考以下文章
Flutter futureBuilder 正在渲染未知的褪色卡片