flutter中NestedScrollView在pin头的时候body会滚动到头下面

发布于 2022-09-11 22:54:55 字数 5660 浏览 49 评论 0

我用NestedScrollView中增加一个自定义可pin的头以及一个列表,目的是列表滑动的时候头部收缩,但发现了一个问题,列表会滚动到头的下面,这导致我的列表悬浮头被掩盖了。

尝试了SliverOverlapAbsorber 和 SliverOverlapInjector无效

代码如下

import 'package:flutter/material.dart';
import 'package:pure_account_book/component/transactionListItem.dart';
import 'package:pure_account_book/model/account.dart';
import 'package:pure_account_book/model/category.dart';
import 'package:pure_account_book/model/transaction.dart';
import 'package:sticky_headers/sticky_headers.dart';

class TransactionPage extends StatefulWidget {
  @override
  State createState() {
    return _TransactionPage();
  }
}

class _TransactionPage extends State
    with AutomaticKeepAliveClientMixin {
  //通过AutomaticKeepAliveClientMixin页面保活
  CategoryModels paymentCategoryModels;
  CategoryModels incomeCategoryModels;
  AccountModels accountModels;
  TransactionModels transactionModels;
  bool dataReady = false;

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  void _loadData() async {
    paymentCategoryModels =
        CategoryModels.fromTable(CategoryModels.paymentCategoryTableName);
    await paymentCategoryModels.loadData();
    incomeCategoryModels =
        CategoryModels.fromTable(CategoryModels.incomeCategoryTableName);
    await incomeCategoryModels.loadData();
    accountModels = AccountModels.fromTable(AccountModels.accountTableName);
    await accountModels.loadData();
    transactionModels =
        TransactionModels.fromTable(TransactionModels.transactionTableName);
    await transactionModels.loadDataFromTable(
        incomeCategoryModels, paymentCategoryModels, accountModels);
    setState(() {
      dataReady = true;
    });
//    await _cacheImage();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: dataReady
          ? Scaffold(
              body: NestedScrollView(headerSliverBuilder:
                  (BuildContext context, bool innerBoxIsScrolled) {
              return [


                SliverOverlapAbsorber(
                  handle:
                      NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  child: SliverPersistentHeader(
                    delegate: DemoHeader(),
                    pinned: true,
                  ),
                ),
              ];
            }, body: SafeArea(
                top: false,
                bottom: false,
              child: Builder(
                builder: (BuildContext context) {
                  return CustomScrollView(
                    slivers: [
                      SliverOverlapInjector(
                        // This is the flip side of the SliverOverlapAbsorber above.
                        handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
                            context),
                      ),
                      SliverPadding(
                          padding: const EdgeInsets.all(1.0),
                      sliver:SliverList(
                        delegate: SliverChildBuilderDelegate((context, index) {
                          return StickyHeader(
                              header: _buildItemHeader(index),
                              content: _buildItem(index));
                        },
                            childCount:
                                transactionModels.transactionDateList.length),
                      )
                      )
                    ],
                  );
                },
              ),
            )))
          : null,
    );
  }

  Widget _buildItem(int index) {
    String date = transactionModels.transactionDateList[index];
    TransactionDayModel transactionDayModel =
        transactionModels.transactionDaysMap[date];
    List widgetList = List();
    for (var transactionModel in transactionDayModel) {
      TransactionListItem transactionListItem = TransactionListItem(
        comment: transactionModel.comment,
        categoryName: transactionModel.categoryName,
        categoryIcon: transactionModel.categoryIcon,
        categoryColor: transactionModel.categoryColor,
        accountName: transactionModel.accountName,
        amount: transactionModel.amountString,
        timestamp: transactionModel.timestampDateTime,
        categoryType: transactionModel.transactionType,
      );

      widgetList.add(transactionListItem);
    }
    return Column(
      children: widgetList,
    );
  }


  Widget _buildItemHeader(int index) {
    TransactionDayModel transactionDayModel =
        transactionModels.getTransactionDayModelByIndex(index);

    return TransactionListItemHeader(
      dateTime: transactionDayModel.dateTime,
      payment: transactionDayModel.payment,
      income: transactionDayModel.income,
    );
  }

  void _onPressed() {
    Navigator.pushNamed(context, 'transaction_edit');
  }

  @override
  bool get wantKeepAlive => true;
}

class DemoHeader extends SliverPersistentHeaderDelegate {
  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    debugPrint(shrinkOffset.toString());
    return Container(
        color: Color(0xbbff0000),
        alignment: Alignment.center,
        child: Text('我是一个头部部件',
            style: TextStyle(color: Colors.white, fontSize: 30.0)));
  } 

  @override
  double get maxExtent => 300.0; 

  @override
  double get minExtent => 180.0; 

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return true;
  }
}

效果如下:
GIF 2019-10-14 9-10-43.gif

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神魇的王 2022-09-18 22:54:55

解决办法:
使用国内大神修改的
extended_nested_scroll_view
https://pub.flutter-io.cn/pac...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文