如何在Flutter中通知流更新

ioekq8ef  于 2023-01-09  发布在  Flutter
关注(0)|答案(2)|浏览(210)

我正在尝试在我的Flutter应用中实现分页,但这是我第一次这么做。我的想法是创建一个Stream的数据,每当用户到达列表底部时,它就会更新。我没有成功地实现这一点。我目前的代码具有获取新数据并将其添加到现有数据的逻辑。但是现在它甚至没有返回第一个数据范围,所以快照是空的。至于分页功能,我尝试使用ChangeNotifier通知Stream更新,但我不知道这是否有效。请看一下下面的代码,然后告诉我应该修改什么。
DataProvider类:

class DataProvider extends ChangeNotifier{
  DataProvider() : super();

  static var changeController = ChangeNotifier();

  static void reload() {
    changeController.notifyListeners();
  }

  static int lastRange = 0;

  static List data = [];

  static Stream<List> paginatedUsersAndPosts() async* {
    List<UserSearchResult> usersList = data.first;
    List<Post> postsList = data.last;

    print('Notifier');

    changeController.addListener(() async {
      print('Change notified, getting data');

      List<int> range() {
        if (lastRange == 0) {
          lastRange = 10;
          return [0, 10];
        } else {
          // Example 0, 10 => 11, 20
          int newMin = lastRange + 1;
          int newMax = lastRange + 10;
          lastRange = newMax;
          return [newMin, newMax];
        }
      }

      List<Map<String, dynamic>> postsDocs = await Supabase.db
          .from('posts')
          .select()
          .order('date', ascending: false)
          .range(range().first, range().last);
      List<Post> newPostsList =
      postsDocs.map((postDoc) => Post.fromJson(postDoc)).toList();

      newPostsList.forEach((post) async {
        postsList.add(post);

        if (usersList.where((u) => u.uid == post.uid).isNotEmpty) {
          Map<String, dynamic> userDoc =
          await Supabase.db.from('profiles').select().single();

          ProfileInfoObject profileInfo = ProfileInfoObject.fromJson(userDoc);
          print('New profile: $profileInfo');
          Profile profile = Profile(profileInfo, []);
          profile.posts.add(post);
          List blockedUsers = userDoc['blockedUsers'] as List;
          UserSearchResult user = (UserSearchResult(
              profile, userDoc['uid'].toString(), blockedUsers));

          usersList.add(user);
        }
      });
    });

    yield [usersList, postsList];
  }
}

使用流的主要小部件:

class FloatingTabBarView extends StatefulWidget {
  const FloatingTabBarView({Key? key}) : super(key: key);

  @override
  State<FloatingTabBarView> createState() => _FloatingTabBarViewState();
}

class _FloatingTabBarViewState extends State<FloatingTabBarView> {

  @override
  void initState() {
    PermissionsService.checkPermissions(context);

    DataProvider.reload();
    super.initState();
  }

    Stream<List> stream = DataProvider.paginatedUsersAndPosts();

    return StreamBuilder<List>(
        stream: stream,
        builder: (context, AsyncSnapshot<List<dynamic>> snapshot) {
          ...
        });
  }

  @override
  Widget build(BuildContext context) {
    return floatingTabBarPageView();
  }
}
fcwjkofz

fcwjkofz1#

请看一下pull_to_refresh包。这允许实现拉取以刷新和增量加载数据。使用RefreshController在数据刷新或加载时进行更新。
1.示例化RefreshController
1.用SmartRefresher包裹ListView
1.实现onLoading回调以增量方式获取数据
1.完成或出错时更新RefreshController
这个软件包有一个很好的用法示例,请一定要去看看。

nkoocmlb

nkoocmlb2#

问题在于我创建流的方式,因为我把Stream作为函数,所以我无法调用该函数来重新加载,而是把代码移到一个可以从任何页面调用的static void中,创建一个StreamController,并在void的末尾使用controller.add(data),这样我就可以用新数据更新流。

相关问题