如何将 Future<Widget> 作为小部件返回

Posted

技术标签:

【中文标题】如何将 Future<Widget> 作为小部件返回【英文标题】:How to return Future<Widget> as Widget 【发布时间】:2020-10-21 18:12:15 【问题描述】:

下面的代码可能看起来有点复杂,但基本上下面的函数使用一个 switch case 根据导航栏的索引号返回正确的小部件。我面临的问题是,当脚手架的主体必须根据导航栏的索引号获取正确的页面时,它告诉我我不能拥有Future &lt;Widget&gt; 的类型 而不是一种 Widget 作为我脚手架的主体。我预计会发生这种情况,但是我不知道如何添加 await 关键字,以便该类型是有效的小部件。谢谢你的帮助。 PS。请查看 cmets,它告诉我要在下面的代码中调用函数的位置。

Future<Widget> getCorrespondingPage(int index) async 
    bool isFromGoogleSignIn;
    String displayName = await InformationFinder().getUserName(_auth);
    String provider = await ProviderFinder().getProvider(_auth);
    String profilePicture = await InformationFinder().getProfilePicture(_auth);
    if (provider == 'Google') 
      setState(() 
        isFromGoogleSignIn = true;
      );
     else 
      setState(() 
        isFromGoogleSignIn = false;
      );
    
    switch (index) 
      case 0:
        return SideBarLayoutStateful(
          app: SmartVetScreen(),
          isFromGoogleSignIn: isFromGoogleSignIn,
          profilePicture: profilePicture,
          displayName: displayName,
        );
        break;
      case 1:
        return SideBarLayoutStateful(
          app: SmartReminderScreen(),
          isFromGoogleSignIn: isFromGoogleSignIn,
          profilePicture: profilePicture,
          displayName: displayName,
        );
      default:
        return null;
    
  

这是我完成的有状态小部件:

class _NavigationBarScreenState extends State<NavigationBarScreen> 
  int currentIndex = 0;
//THIS IS WHERE THE ABOVE FUNCTION WAS CREATED
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: currentIndex,
          type: BottomNavigationBarType.shifting,
          iconSize: 27.0,
          elevation: 10.0,
          selectedFontSize: 18.0,
          unselectedFontSize: 15.0,
          items: [
            BottomNavigationBarItem(
              icon: Icon(FontAwesomeIcons.stethoscope),
              title: Text('Smart Vet'),
              backgroundColor: Colors.green.shade200,
            ),
            BottomNavigationBarItem(
              icon: Icon(FontAwesomeIcons.bell),
              title: Text('Smart Remind'),
              backgroundColor: Colors.purple.shade100,
            ),
          ],
          onTap: (index) 
            setState(() 
              currentIndex = index;
            );
          ,
        ),
//THIS IS WHERE I NEED TO GET BACK THE WIDGET FROM THE getCorrespondingPage() method
        body: ,
      ),
    );
  


【问题讨论】:

【参考方案1】:

期货必须等待。在您的情况下,您在渲染过程中使用期货,并且由于由于未来位于小部件树的中间而等待未来的过程已经开始,因此您必须等待未来使用一些特殊方法的小部件树。你可以使用FutureBuilder

分离数据获取和小部件渲染并使用FutureBuilder等待Future

Future<Map<String, String>> getData() async 
  String displayName = await InformationFinder().getUserName(_auth);
  String provider = await ProviderFinder().getProvider(_auth);
  String profilePicture = await InformationFinder().getProfilePicture(_auth);

  return 
    'displayName': displayName,
    'provider': provider,
    'profilePicture': profilePicture
  ;


Widget getCorrespondingPage(int index) 
  return FutureBuilder<Map<String, String>>(
    future: getData,
    builder: (context, snapshot) 
      if (snapshot.hasData) 
        final displayName = snapshot.data['displayName'];
        final provider = snapshot.data['provider'];
        final profilePicture = snapshot.data['profilePicture'];

        bool isFromGoogleSignIn = provider == 'google';
        switch (index) 
          case 0:
            return SideBarLayoutStateful(
              app: SmartVetScreen(),
              isFromGoogleSignIn: isFromGoogleSignIn,
              profilePicture: profilePicture,
              displayName: displayName,
            );
            break;
          case 1:
            return SideBarLayoutStateful(
              app: SmartReminderScreen(),
              isFromGoogleSignIn: isFromGoogleSignIn,
              profilePicture: profilePicture,
              displayName: displayName,
            );
          default:
            return null;
        
      
    ,
  );

【讨论】:

谢谢,不过你能更详细地解释一下它是如何工作的吗?

以上是关于如何将 Future<Widget> 作为小部件返回的主要内容,如果未能解决你的问题,请参考以下文章

颤振:类型“Future<dynamic>”不是“Widget”类型的子类型?错误

Flutter'Future<void>'不是'Widget'类型的子类型[重复]

参数类型“Future<bool>”不能分配给参数类型“Widget”[Flutter]

Flutter:类型 'Future<dynamic>' 不是类型 'Widget' 的子类型 // MaterialPageRoute<dynamic>(null))

根据闭包上下文的要求,返回类型“Future<Image>”不是“Widget”

如何将 std::future<T> 转换为 std::future<void>?