【问题标题】:Flutter infinite scroll always reset the view颤振无限滚动总是重置视图
【发布时间】:2020-11-23 16:59:50
【问题描述】:

我有一个简单的无限滚动,可以从 API 加载项目。加载更多项目后我的期望,如果更新了新项目列表和我的视口将不会被重置。

这是我的页面

class ArticleListPage extends StatelessWidget {
  final _scrollController = ScrollController();
  final Color color = Colors.black;
  ArticleListBloc _articleListBloc;

  @override
  Widget build(BuildContext context) {
    _articleListBloc = BlocProvider.of<ArticleListBloc>(context);
    return Scaffold(
      backgroundColor: color,
      body: BlocBuilder<ArticleListBloc, ArticleListState>(
        builder: (context, ArticleListState state) {
          if (state.searching) {
            return Center(
              child: CircularProgressIndicator(
                backgroundColor: Colors.white,
              ),
            );
          } else {
            return NotificationListener<ScrollNotification>(
              onNotification: _handleScrollNotification,
              child: ListView.builder(
                shrinkWrap: true,
                itemCount: calculateListItemCount(state),
                controller: _scrollController,
                physics: AlwaysScrollableScrollPhysics(),
                itemBuilder: (context, index) {
                  return index >= state.listItems.length
                      ? Center(
                          child: CircularProgressIndicator(),
                        )
                      : ArticleListViewItem(article: state.listItems[index]);
                },
              ),
            );
          }
        },
      ),
    );
  }

  bool _handleScrollNotification(ScrollNotification notification) {
    if (notification is ScrollEndNotification &&
        _scrollController.position.extentAfter == 0) {
      _articleListBloc.add(GetArticles());
    }
    return false;
  }

  int calculateListItemCount(ArticleListState state) {
    if (state.hasReachedEndOfResults) {
      return state.listItems.length;
    } else {
      return state.listItems.length + 1;
    }
  }
}

还有我的集团

class ArticleListBloc extends Bloc<ArticleListEvent, ArticleListState> {
  final ArticleDataSource dataSource;

  ArticleListBloc(this.dataSource) : super(ArticleListState.initial());

  @override
  Stream<ArticleListState> mapEventToState(ArticleListEvent event) async* {
    String searchKeyword = state.searchKeyword;
    int pageNumber = state.pageNumber;
    bool hasReachEndResult = state.hasReachedEndOfResults;
    BuiltList<Article> currentArticles = state.listItems;
    if (event is SetKeyword) {
      searchKeyword = event.keyword;
      pageNumber = 0;
      currentArticles = new BuiltList<Article>();
      hasReachEndResult = false;
    }
    if (!hasReachEndResult) {
      yield state.rebuild((b) => b..searching = true);
      final articles = await dataSource.getArticles(pageNumber, searchKeyword);
      if (articles.isEmpty) {
        hasReachEndResult = true;
      } else {
        hasReachEndResult = false;
      }
      yield ArticleListState.success(currentArticles + articles, pageNumber + 1,
          searchKeyword, hasReachEndResult);
    }
  }
}

不知何故,在搜索(加载更多)后,我可以看到第一个项目再次被重绘,尽管项目已正确添加到列表中,但我不得不再次向下滚动。

我是否需要某种skip 变量才能转到第一个新添加的项目?我在这里还缺少什么?

【问题讨论】:

    标签: flutter


    【解决方案1】:

    问题在于构建小部件函数中的第一个 if 条件。应该是

             if (state.listItems.isEmpty) {
                return Center(
                  child: CircularProgressIndicator(
                    backgroundColor: Colors.white,
                  ),
                );
              }
    

    这样CircularProgressIndicator只会在第一次搜索时被绘制,而随后的搜索及其进度已经由indicator in处理

                    itemBuilder: (context, index) {
                      return index >= state.listItems.length
                          ? Center(
                              child: CircularProgressIndicator(),
                            )
                          : ArticleListViewItem(article: state.listItems[index]);
                    },
    

    【讨论】:

      猜你喜欢
      • 2021-12-22
      • 2020-03-09
      • 2020-02-19
      • 2020-01-18
      • 2020-06-19
      • 2012-02-25
      • 2020-01-27
      • 2021-12-21
      • 2021-07-22
      相关资源
      最近更新 更多