android - 如何重新加载 future 数据的屏幕

标签 android flutter dart android-widget future

我有带有六个选项卡的 TabBarView。 我试图在第一个选项卡中显示所有已安装的应用程序。

即使在 apps 已填满后,也会显示 CircularProgressIndicator。重新访问第一个选项卡后,应用程序就会列出。

AppScreenC 为第一个选项卡调用。

final model = AppModel();

class AppScreenC extends StatefulWidget {
  @override
  _AppScreenCState createState() => _AppScreenCState();
}

class _AppScreenCState extends State<AppScreenC> {
  List<Application> apps = model.loadedApps();
      
  @override
  Widget build(BuildContext context) => _buildApps();

  Widget _buildApps() => apps != null
      ? ListView.builder(
          itemCount: apps.length,
          itemBuilder: (BuildContext context, int index) =>
              _buildRow(apps[index]))
      : Center(child: CircularProgressIndicator());

  Widget _buildRow(ApplicationWithIcon app) {
    final saved = model.getApps().contains(app.apkFilePath);
    return ListTile(
      leading: Image.memory(app.icon, height: 40),
      trailing: saved
          ? Icon(Icons.check_circle, color: Colors.deepPurple[400])
          : Icon(Icons.check_circle_outline),
      title: Text(app.appName),
      onTap: () => setState(() => saved
          ? model.removeApp(app.apkFilePath)
          : model.addApp(app.apkFilePath)),
    );
  }
}

AppModel 类具有所有必要的方法。

  class AppModel{
  final _saved = Set<String>();
  List<Application> apps;

  AppModel() {
    loadApps();
  }

  Set<String> getApps() {
    return _saved;
  }

  addApp(String apkPath) {
    _saved.add(apkPath);
  }

  removeApp(String apkPath) {
    _saved.remove(apkPath);
  }

  loadApps() async {
    apps = await DeviceApps.getInstalledApplications(
        onlyAppsWithLaunchIntent: true,
        includeSystemApps: true,
        includeAppIcons: true);
    apps.sort((a, b) => a.appName.compareTo(b.appName));
  }

  loadedApps() => apps;
}

发生这种情况是因为第一次调用屏幕时 apps 为空。它在后台加载应用程序。再次访问屏幕时,将显示应用程序。

欢迎任何帮助

最佳答案

您可以做的是在函数完成后调用setState()。您需要更改loadedApp以返回Future:

class AppScreenC extends StatefulWidget {
  @override
  _AppScreenCState createState() => _AppScreenCState();
}

class _AppScreenCState extends State<AppScreenC> {
  @override
 void initState(){
 super.initState();
 model.loadApps().then((loadedApps){ //loadApps() will return apps and you don't need loadedApps() method anymore
 setState((){ //rebuilds the screen
  apps = loadedApps
   })});
}
      
  @override
  Widget build(BuildContext context) => _buildApps();

  Widget _buildApps() => apps != null
      ? ListView.builder(
          itemCount: apps.length,
          itemBuilder: (BuildContext context, int index) =>
              _buildRow(apps[index]))
      : Center(child: CircularProgressIndicator());

  Widget _buildRow(ApplicationWithIcon app) {
    final saved = model.getApps().contains(app.apkFilePath);
    return ListTile(
      leading: Image.memory(app.icon, height: 40),
      trailing: saved
          ? Icon(Icons.check_circle, color: Colors.deepPurple[400])
          : Icon(Icons.check_circle_outline),
      title: Text(app.appName),
      onTap: () => setState(() => saved
          ? model.removeApp(app.apkFilePath)
          : model.addApp(app.apkFilePath)),
    );
  }
}

您的AppModel将如下所示:

class AppModel{
  final _saved = Set<String>();
  List<Application> apps;

  AppModel() {
    loadApps();
  }

  Set<String> getApps() {
    return _saved;
  }

  addApp(String apkPath) {
    _saved.add(apkPath);
  }

  removeApp(String apkPath) {
    _saved.remove(apkPath);
  }

  Future loadApps() async {
    apps = await DeviceApps.getInstalledApplications(
        onlyAppsWithLaunchIntent: true,
        includeSystemApps: true,
        includeAppIcons: true);
    apps.sort((a, b) => a.appName.compareTo(b.appName));
    return Future.value(apps);
  }

}

您还可以按照评论中的建议使用FutureBuilder

关于android - 如何重新加载 future 数据的屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63763836/

相关文章:

Android sqlite 查询字符串

java - 通过反射调用抽象方法

android - Flutter:共享存储(存储访问框架 API)隐藏子目录中文件的权限不起作用

flutter - 重新安装Flutter和Dart时生成错误(导入错误)

android - 如何将数据从网站服务器发送到Android应用程序

Android XML 首选项问题。不能让它持久

flutter - 卡住如何在顶级模型上分配我自己的 JsonConverter?

android - flutter : change position of text on the appbar

flutter - 序列化 Dart 映射

flutter - 对 flutter/dart 中的 future 错误进行单元测试的正确方法是什么?