使用Futurebuilder有条件地渲染小部件

时间:2019-09-24 20:57:06

标签: flutter dart

我是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

我在how to assign future<> to widget in flutter?读到了有关Futurebuilder的信息,这看起来很可行,因此我将构建方法修改为

Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: FutureBuilder(
          future: loadWidget(),
          builder: (BuildContext context, AsyncSnapshot<Widget> widget){
            return widget;
          },
        ),
      ),
    );
  }

但这给了我以下错误:

  

返回类型'AsyncSnapshot'不是定义的'Widget'   通过匿名关闭。

我该如何完成?谢谢!

2 个答案:

答案 0 :(得分:2)

您做得对,但问题出在FutureBuilder返回的对象上,请参见此代码中的注释:

// *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)的清洁,然后在widget.data中使用FutureBuilder捕获状态,然后根据FutureBuilder内部的Auth状态。

答案 1 :(得分:0)

我将把未来移到FutureBuilder中,然后将逻辑放入其中

var words = [
  "low tide",
  "kayak",
  "coral",
  "boat",
  "beachball",
  "hermit crab",
  "sunscreen"
];

//and then ive generated an underscore already to show up on the screen `
function generateUnderscore() {
    for (let i = 0; i < chosenWord.length; i++) {
        underScore.push("_");
    }
    return underScore;
}