首页 > 解决方案 > 带有 NestedScrollview 的 RefreshIndicator

问题描述

我想要 2 个带有 ListView 的标签页,每个标签页共享一个 RefreshIndicator。但是,RefreshIndicator 必须具有 Scrollable 作为子项(TabBarView 不是),因此我尝试为每个选项卡制作 2 个 RefreshIndicator,如下面的代码所示。

但这带来了一个不同的问题,我还想要一个浮动的 AppBar,这意味着我必须使用 NestedScrollView。因此,每当我向下滚动时,我最终都会触发 RefreshIndicators 的 onRefresh 方法。而我只需要一个来刷新。

import 'package:flutter/material.dart';

main() {
    runApp(
        MaterialApp(
            home: DefaultTabController(
                length: 2,
                child: Scaffold(
                    body: NestedScrollView(
                        headerSliverBuilder: (context, innerBoxIsScrolled) {
                            return [
                                SliverAppBar(
                                    floating: true,
                                    snap: true,
                                    bottom: TabBar(
                                        tabs: [
                                            Tab(text: 'Page1'),
                                            Tab(text: 'Page2'),
                                        ],
                                    ),
                                ),
                            ];
                        },
                        body: TabBarView(
                            children: [
                                Page(1),
                                Page(2),
                            ],
                        ),
                    ),
                ),
            ),
        ),
    );
}

class Page extends StatefulWidget {
    final pageNumber;
    Page(this.pageNumber);
    createState() => PageState();
}

class PageState extends State<Page> with AutomaticKeepAliveClientMixin {
    get wantKeepAlive => true;

    build(context){
        super.build(context);
        return RefreshIndicator(
            onRefresh: () => Future(() async {
                print('Refreshing page no. ${widget.pageNumber}');  // This prints twice once both tabs have been opened
                await Future.delayed(Duration(seconds: 5));
            }),
            child: ListView.builder(
                itemBuilder: ((context, index){
                    return ListTile(
                        title: Text('Item $index')
                    );
                }),
            )
        );
    }
}

AutomaticKeepAliveClientMixin 可以防止每次我切换选项卡时重新构建页面,因为这在我的实际应用程序中是一个昂贵的过程。

对两个选项卡使用单个 RefreshIndicator 的解决方案将是最理想的,但感谢您提供任何帮助。

标签: dartflutter

解决方案


这段代码对我有用,它主要建立在@Nuts 答案之上,但它需要一些调整,我的编辑被拒绝

DefaultTabController(
      length: tabs.length,
      child: RefreshIndicator(
        notificationPredicate: (notification) {
          // with NestedScrollView local(depth == 2) OverscrollNotification are not sent
          return notification.depth == 2;
        },
        onRefresh: () => Future.value(null),
        child: NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return [
              SliverAppBar(...)
            ];
          },
          body: TabBarView(
            children: tabs,
          ),
        ),
      ),
    )

推荐阅读