Flutter Future <String> 不能分配给参数类型字符串

Posted

技术标签:

【中文标题】Flutter Future <String> 不能分配给参数类型字符串【英文标题】:Flutter Future <String > cant be assigned to parameter type string 【发布时间】:2020-08-25 09:15:44 【问题描述】:

我有一个future,它会返回一个字符串类型的leadid。

Future<String> getleader() async 
    final DocumentSnapshot data = await Firestore.instance
        .collection('groups')
        .document(widget.detailDocument.data['groupId']).get();
    String leadid = data.data['leader'];
  return leadid;
  

我想在这里使用该值返回。 列表瓦片( 标题:文本(getleader()), 领导:文本('领导者:'), ),

它说未来的字符串不能分配给参数字符串。

我也尝试添加一个函数来等待结果,如下所示

 getdata2() async 
    String lead1= await getleader();

但它也显示错误 Future dynamcic is not a subtype of type string

这是我想要使用未来值的地方

  Widget _memebrprofile() 
    return FutureBuilder(
        future: getleader(),
        builder: (context, snapshot) 
          if (snapshot.hasData) 
            // store the value of the Future in your string variable
            storeValue = snapshot.data;
            return storeValue;
          
          return Scaffold(
            drawer: newdrawer(),
            appBar: AppBar(
              title: Text('User Details'),
            ),
            body: SingleChildScrollView(
              child: ConstrainedBox(
                constraints: BoxConstraints(),
                child: Column(
                  children: <Widget>[
                    ListTile(
                      title: SelectableText(
                        widget.detailDocument.data["groupId"] ?? '',
                      ),
                      leading: Text('Group Id :'),
                    ),
                    ListTile(
                      title: Text(storeValue),//this is where i want to display the string
                      leading: Text('Leader :'),
                    ),
                    Row(
                      children: <Widget>[
                        Flexible(
                          child: RaisedButton(
                            onPressed: () 
             //this is where i want to use it as a string value to check a certain bool.                if (storeValue == _uid()) 
                                Firestore.instance
                                    .collection('users')
                                    .document(widget.detailDocument.documentID)
                                    .updateData(
                                  'groupId': "",
                                );
                                Navigator.of(context).pop();
                                Navigator.pushNamed(context, assignedTask.id);
                               else 
                            ,
                            child: Text('Remove user'),
                          ),
                        ),
                        /* Flexible(
                          child:RaisedButton(
                            onPressed: () 

                            ,
                            child: Text('Changerole to user'),
                          ),),
                          Flexible(
                            child: RaisedButton(
                              onPressed: () 

                              ,
                              child: Text('Changerole to Admin'),
                            ),
                          ),*/
                        Flexible(
                          child: RaisedButton(
                            onPressed: () async 
                              FirebaseAuth auth = FirebaseAuth.instance;
                              final FirebaseUser user =
                                  await auth.currentUser();
                              final userid = user.uid;
                              if (widget.detailDocument.documentID == userid) 
                                Navigator.pushNamed(context, MyProfile.id);
                               else 
                            ,
                            child: Text('Edit Profile'),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          );
        );
  

【问题讨论】:

【参考方案1】:

尝试以下方法:

          FutureBuilder(
            future: getleader(),
            builder: (context, AsyncSnapshot<String> snapshot) 
              if (snapshot.connectionState == ConnectionState.done) 
                return ListView.builder(
                    shrinkWrap: true,
                    itemCount: 1,
                    itemBuilder: (BuildContext context, int index) 
                      return ListTile(
                        contentPadding: EdgeInsets.all(8.0),
                        title:
                            Text(snapshot.data),
                      );
                    );
               else if (snapshot.connectionState == ConnectionState.none) 
                return Text("No data");
              
              return CircularProgressIndicator();
            ,
          ),

Future<String> getleader() async 
    final DocumentSnapshot data = await Firestore.instance
        .collection('groups')
        .document(widget.detailDocument.data['groupId']).get();
    String leadid = data.data['leader'];
  return leadid;
  

您收到上述错误的原因是因为getleader() 返回一个Future&lt;String&gt; 并且Text 小部件采用String 类型的值,因此使用FutureBuilder 然后您可以获得Future 的值并在 Text 小部件中使用它。

【讨论】:

上述工作完美我已经尝试过了,但我有一个小问题,因为我想将上面的 snapshot.data 存储在一个变量中,以便我可以在其他部分使用它来检查条件 itemBuilder: (BuildContext context, int index) value = snapshot.data; 这会将其存储在 value 值字符串在未来构建器之外显示为空 @RavitejaReddy 使用 setState【参考方案2】:

您收到错误是因为您没有使用FutureBuilder。 尝试使用FutureBuilder。 您可以通过将小部件包装在 FutureBuilder 中来解决它。 检查下面的代码:它工作得很好。

    // use a future builder
    return FutureBuilder<String>(
      // assign a function to it (your getLeader method)
      future: getleader(),
        builder: (context, snapshot) 
        if(snapshot.hasData)
          // print your string value
          print(snapshot.data);
          return new ListTile(
              leading: Text('Leader'),
              title: Text(snapshot.data),
              onTap: () 
              
          );
         else 
          return Text(snapshot.error.toString());
        
        
    );

我希望这会有所帮助。

更新 根据要求将值(字符串)存储到变量中,请检查以下代码:

// declare your variable 
String storeValue;
    return FutureBuilder<String>(
      // assign a function to it (your getLeader method)
      future: getleader(),
        builder: (context, snapshot) 
        if(snapshot.hasData)
          // store the value of the Future in your string variable
          storeValue = snapshot.data;
          return new ListTile(
              leading: Text('Leader'),
              title: Text(snapshot.data),
              onTap: () 
              
          );
         else 
          return Text(snapshot.error.toString());
        
        
    );

【讨论】:

我想将数据 snapshot.data 存储到一个变量中,因为我必须在类中的其他地方使用它来检查布尔值;我如何将它存储在变量中 我得到了 title 中的值;但是在此构建器之外使用时,storevalue 返回 null 发布你分配给变量@RavitejaReddy的代码【参考方案3】:

您可以在StatefulWidget 中创建另一个函数,使用setState() 更新您的lead1

  String lead1 = "";

  getLeadID() 
    getLeader().then((val) => setState(() 
          lead1 = val;
        ));
  

.then(val) 等待getLeader() 完成,然后允许您使用返回值val

编辑:

将 ListTile 中的文本设置为lead1 变量,例如

 ListTile( title: Text(lead1), leading: Text('Leader :'), ),

然后在initState()中调用getLeadID()函数,像这样;

class _MyHomePageState extends State<MyHomePage> 

  String lead1 = "";

  @override
  void initState() 
    super.initState();
    getLeadID();
  

  @override
  Widget build(BuildContext context) 
  //rest of code

【讨论】:

它返回一个空值 你是如何使用它的?将ListTile 中的文本设置为lead1,然后在initState() 中调用getLeadID()。我已经编辑了我的答案,向您展示如何做。

以上是关于Flutter Future <String> 不能分配给参数类型字符串的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Future <String> 不能分配给参数类型字符串

Flutter/Dart - 调用一个 Future<String> ...但只需要返回一个 String 的函数

将 Future<List> 从 Firestore 转换为 List<String> - Flutter Firebase [重复]

Flutter 通过查询 Firestore 创建自定义用户模型给出“类型‘Future<dynamic>’不是‘String’类型的子类型”错误

Flutter 在另一个页面上获取用户 ID 并将其转换为字符串(“类型'Future<dynamic>'不是类型'String'的子类型”)

Flutter:从 Future 中获取价值的正确方法