【问题标题】:Flutter - how using SliverAppBar with Infinite Scroll Pagination?Flutter - 如何将 SliverAppBar 与无限滚动分页一起使用?
【发布时间】:2022-01-18 23:51:33
【问题描述】:

我在我的颤振应用程序中使用Infinite Scroll Pagination 插件。我还需要在我的页面中使用 SilverAppBar。这是我的代码:

return Scaffold(
  body: DefaultTabController(
    length: 2,
    child: NestedScrollView(
      headerSliverBuilder: (context, value) {
        return [
          SliverAppBar(
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.call), text: "1"),
                Tab(icon: Icon(Icons.message), text: "2"),
              ],
            ),
          ),
        ];
      },
      body: TabBarView(
        children: [
          const MyListWidget()
          Text('2')
        ],
      ),
    ),
  ),
);

这是我的 MyListWidget:

Widget build(BuildContext context) {
return PagedSliverList<int, MyModel>(
      pagingController: _сontroller,
      builderDelegate: PagedChildBuilderDelegate<MyModel>(
        itemBuilder: (context, item, index) {
          return Text(item.Title);
        },
      ),
    );
  }

但我有错误:

A RenderRepaintBoundary expected a child of type RenderBox but received a child of type RenderSliverList.

我也试过了:

body: SliverFillRemaining(
            child: TabBarView(
              children: [
                const ProfileSelections(),
                //Container(child: Text('1')),
                Text('2')
              ],
            ),
          )

但我有错误:

 A RenderSliverFillRemainingWithScrollable expected a child of type RenderBox but received a child of type RenderSliverFillRemainingWithScrollable.

如何解决这些错误?任何建议 - 我将不胜感激

【问题讨论】:

  • 你能分享一下你实际上想要得到什么吗?

标签: flutter dart flutter-layout infinite-scroll


【解决方案1】:

发生这种情况是因为tabBarView 需要正常的box children 而不是slivers,因为它默认使用综合浏览量,您可以在official documentation 中阅读。

如果您使用普通列表而不是像下面这样的条子,它将解决问题:

Widget build(BuildContext context) {
return  PagedListView<int, MyModel>(
      pagingController: _сontroller,
      builderDelegate: PagedChildBuilderDelegate<MyModel>(
        itemBuilder: (context, item, index) {
          return Text(item.Title);
        },
      ),
    );
  }

【讨论】:

    【解决方案2】:

    无需使用Infinite scroll pagination,只需使用flutter内置的滚动通知即可。

    滚动通知 - 抽象类 ScrollNotification 使用 ViewportNotificationMixin 扩展了 LayoutChangedNotification。

    与滚动相关的通知。

    可滚动小部件通知其祖先有关滚动相关的更改。

    通知具有以下生命周期:

    • 一个 ScrollStartNotification,表示该小部件已 开始滚动。

    • 零个或多个 ScrollUpdateNotifications,表示 小部件已更改其滚动位置,混合了零个或多个

    • OverscrollNotifications,表示小部件没有 改变了它的滚动位置,因为改变会导致它的 滚动位置超出其滚动边界。穿插 滚动更新通知和 OverscrollNotifications 是零个或多个 UserScrollNotifications, 这表明用户已经改变了他们的方向 正在滚动。

    • 一个 ScrollEndNotification,表示该小部件已停止 滚动。

    • 一个 UserScrollNotification,其 UserScrollNotification.direction 为 ScrollDirection.idle。

    这里是完整的源代码和解释

    import 'package:flutter/material.dart';
    
    class InfiniteScrollPagination extends StatefulWidget {
      const InfiniteScrollPagination({Key key}) : super(key: key);
    
      @override
      _InfiniteScrollPaginationState createState() =>
          _InfiniteScrollPaginationState();
    }
    
    class _InfiniteScrollPaginationState extends State<InfiniteScrollPagination> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: DefaultTabController(
            length: 2,
            child: NestedScrollView(
              headerSliverBuilder: (context, value) {
                return [
                  SliverAppBar(
                    pinned: true,
                    toolbarHeight: 0,
                    bottom: TabBar(
                      tabs: [
                        Tab(icon: Icon(Icons.call), text: "1"),
                        Tab(icon: Icon(Icons.message), text: "2"),
                      ],
                    ),
                  ),
                ];
              },
              body: TabBarView(
                children: [MyListWidget(), Text('2')],
              ),
            ),
          ),
        );
      }
    }
    
    class MyListWidget extends StatefulWidget {
      const MyListWidget({Key key}) : super(key: key);
    
      @override
      State<MyListWidget> createState() => _MyListWidgetState();
    }
    
    class _MyListWidgetState extends State<MyListWidget> {
      int count = 15;
    
      @override
      Widget build(BuildContext context) {
        return NotificationListener<ScrollNotification>(
          onNotification: (ScrollNotification scrollInfo) {
            if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent) {
              // here you update your data or load your data from network
              setState(() {
                count += 10;
              });
            }
            return true;
          },
          // if you used network it would good to use the stream or future builder
          child: Container(
            child: getDataList(count),
          ),
        );
      }
    }
    
    getDataList(listOfData) {
      return ListView.separated(
          itemBuilder: (context, index) {
            return ListTile(
              title: Text("index $index"),
            );
          },
          separatorBuilder: (context, index) => Divider(
            thickness: 2,
            color: Colors.grey,
          ),
          itemCount: listOfData);
    }
    
    

    输出:

    【讨论】:

      【解决方案3】:

      使用PagedListView 而不是PagedSliverList 可以解决问题。 Slivers 不是小部件,Slivers 以不同的方式呈现。我们主要在CustomScrollView 小部件中使用Slivers

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-07
        • 2020-01-07
        • 1970-01-01
        • 1970-01-01
        • 2011-08-16
        • 2017-08-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多