Flutter:防止抽屉在 FutureBuilder 内滑动时始终刷新

Posted

技术标签:

【中文标题】Flutter:防止抽屉在 FutureBuilder 内滑动时始终刷新【英文标题】:Flutter : Prevent Drawer Always Refresh at Swipe inside FutureBuilder 【发布时间】:2020-06-02 01:27:06 【问题描述】:

我有一个让我讨厌抽屉的问题。我在 FutureBuilder 中有抽屉,用于从 API 获取用户配置文件。问题是每次我滑动/打开抽屉,它都会在获取用户配置文件之前刷新。这会带来糟糕的用户体验。

我已经在搜索如何让 FutureBuilder 只从 this 运行一次,但抽屉仍然刷新。

我错过了什么?

抽屉自定义

class _DrysDrawerCustomState extends State<DrysDrawerCustom> 
  Future<List<UserModel>> userList;

  @override
  void didChangeDependencies() 
    super.didChangeDependencies();
    final username = Provider.of<GlobalProvider>(context).username;
    userList = userApi.getUserByUsername(username: username);
  

  @override
  Widget build(BuildContext context) 
    final globalProvider = Provider.of<GlobalProvider>(context, listen: false);
    //TODO Change Structure Drawer
    return FutureBuilder(
      future: userList,
      builder: (BuildContext context, AsyncSnapshot<List<UserModel>> snapshot) 
        if (snapshot.connectionState == ConnectionState.done) 
          if (snapshot.hasError) 
            return ErrorFutureBuilder(errorText: snapshot.error);
           else 
            final user = snapshot.data[0];
            return DrawerCustom(
              imageUrl: "$userApi.baseImageUrl/$user.fotoUser",
              detailUser: [
                Text(user.namaUser),
                Text(user.namaGroup),
              ],
              drawerMenu: [
                DrawerMenu(
                  menuName: "Profil Info",
                  icon: Icons.people_outline,
                  onTap: () => Navigator.of(context)
                      .pushNamed(ProfilInfoScreen.routeNamed),
                ),
                DrawerMenu(
                  menuName: "Ganti Password",
                  icon: Icons.lock,
                  onTap: () => Navigator.of(context)
                      .pushNamed(ChangePasswordScreen.routeNamed),
                ),
                Divider(),
                DrawerMenu(
                  menuName: "Logout",
                  icon: Icons.arrow_back,
                  onTap: () 
                    globalProvider.removeUsername();
                    Navigator.of(context)
                        .pushReplacementNamed(LoginScreen.routeNamed);
                  ,
                ),
              ],
            );
          
         else 
          return LoadingFutureBuilder();
        
      ,
    );
  


全球供应商

GlobalProvider() 
    _initialSharedPreferences();
  
String _username;
  String get username => _username;

  void _initialSharedPreferences() async 
    await getUsername();
  

  Future updateUsername(String username) async 
    SharedPreferences pref = await SharedPreferences.getInstance();
    await pref.setString("username", username);
    //! It's Important !!! After update / remove sharedpreferences  , must called getUsername() to updated the value.
    await getUsername();
    notifyListeners();
  

  Future removeUsername() async 
    SharedPreferences pref = await SharedPreferences.getInstance();
    final result = await pref.remove("username");
    //! It's Important !!! After update / remove sharedpreferences  , must called getUsername() to updated the value.
    await getUsername();
    notifyListeners();
    return result;
  

  Future getUsername() async 
    SharedPreferences pref = await SharedPreferences.getInstance();
    final result = pref.getString("username");
    _username = result;
    notifyListeners();
  

【问题讨论】:

【参考方案1】:

将“user”设为全局变量,并在 build 内部检查 user 是否为 null,然后按照您的操作返回 FutureBuilder(...);否则,只需立即返回 DrawerCustom(...) 。希望这能回答您的问题。

if(user == null)
  return FutureBuilder(...) // don't forget to set user as you've done already
else
  return DrawerCustom(...)

【讨论】:

你的“用户”是什么意思? 我的意思是你从快照中获得的数据:最终用户 = snapshot.data[0];或您使用的任何数据。 @ZeffryReynando 有帮助吗? 它仍然刷新。

以上是关于Flutter:防止抽屉在 FutureBuilder 内滑动时始终刷新的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中收听抽屉打开/关闭动画

如何在 Flutter 中使用路由制作持久抽屉?

flutter上拉抽屉效果 flutter拖动抽屉效果

Flutter:如何在抽屉内推送/弹出导航器页面?

单击底部导航栏时关闭 Flutter 抽屉

Flutter,如何制作按钮以在 Flutter 中打开抽屉 [重复]