您现在的位置是:首页 >学无止境 >Flutter 可冻结的侧滑表格 sticky-headers-table 结合 NestedScrollView 吸顶悬浮的使用实践网站首页学无止境

Flutter 可冻结的侧滑表格 sticky-headers-table 结合 NestedScrollView 吸顶悬浮的使用实践

pengboboer 2024-06-27 00:01:02
简介Flutter 可冻结的侧滑表格 sticky-headers-table 结合 NestedScrollView 吸顶悬浮的使用实践

最近在做flutter web的开发,需要做一个类似云文档中表格固定顶部栏和左侧栏的需求,也就是冻结列表的功能
那么在pub上呢也有不少的开源库,比如:

table_sticky_headers

data_table_2

如果说只是简单的表格和吸顶,那么这两个库就完全可以满足需求,那么到这就不用往下看了

与NestedScrollView结合的吸顶效果实践

实则需求是这样的:希望左侧栏可以悬停的同时,顶部的表头也可以和NestedScrollView的一部分一起悬停在顶部

希望蓝色矩形的这一部分可以吸顶悬停

向上滑到顶的效果(蓝色矩形)

直接撸代码开始实践:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('NestedScrollView with '),
        backgroundColor: Colors.amber,
      ),
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => _buildHeadWidget(context),
        body: StickyHeadersTable(
          columnsLength: titleColumn.length,
          rowsLength: titleRow.length,
          columnsTitleBuilder: (i) => Text(titleColumn[i]),
          rowsTitleBuilder: (i) => Text(titleRow[i]),
          contentCellBuilder: (i, j) => Text(data[i][j]),
          legendCell: Text('Sticky Legend'),
        ),
      ),
    );
  }
List<Widget> _buildHeadWidget(BuildContext context) {
    return [
      SliverToBoxAdapter(
        child: Container(
          alignment: Alignment.center,
          padding: EdgeInsets.symmetric(vertical: 100, horizontal: 30),
          color: Colors.yellow,
          child: Text(
            "header",
            style: TextStyle(fontSize: 65, fontWeight: FontWeight.bold),
          ),
        ),
      ),
      SliverPersistentHeader(
        pinned: true,
        delegate: CommonSilverAppBarDelegate(
          Container(
            height: 100,
            color: Colors.red,
            alignment: Alignment.center,
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                Container(
                  padding: EdgeInsets.symmetric(vertical: 30),
                  child: Text(
                    "persistentHeader",
                    style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
                  ),
                )
                // _buildHeadTabRowWidget()
              ],
            ),
          ),
        ),
      ),
    ];
  }

实现的效果如下图:

数据很少的时候:

整体的效果不尽如人意,用户交互很差劲,主要有这么几个问题:

  1. 表格顶部没有跟随NestedScrollView一起吸顶(其实也是预期能想到的,表头并没有写到PersistentHeader里面)
  2. 滑动body部分的时候,header部分并没有往上滚动,没有那种粘在一起的效果,在滑动到列表最底部的时候,Header才往上一顿一顿的挪动,感觉一卡一卡的,很难受
  3. 在数据量很少的时候会明显的感觉到:向上滑动列表,body里顶部的内容会被吸顶的PersistentHeader遮挡

对于以上问题的解决方案

对于问题1

需要把源码中的头部拿出来,放到NestedScrollView的PersistenHeader里面,这一部分的代码需要提取出来,然后放入PersistenHeader当中

请添加图片描述

并且需要处理ScrollController联动的情况,需要声明一个该插件中的ScrollControllers对象,并且在build的时候拿到源码内的notification回调方法

请添加图片描述
请添加图片描述

对于问题2和3

通过SliverOverlapAbsorber + SliverOverlapInjector的组合可以一起解决

请添加图片描述
请添加图片描述

优化后的效果:

在数据量很少的时候:

项目地址

这是项目demo地址:https://github.com/pengboboer/sticky-headers-table

如果对你有帮助,动动小手给一个star,谢谢。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。