当前位置:首页 > 科技  > 软件

如何在 Flutter 中实现 2D 可滚动的表格,探索 Flutter 中的二维可滚动项,表格解决方案

来源: 责编: 时间:2024-07-11 17:31:19 774观看
导读背景表格是在应用程序中高效组织数据的有用工具。Flutter 的最新更新引入了 TwoDimensionalScrollView 小部件。TwoDimensionalScrollView 是一个小部件,它结合了 TwoDimensionalScrollable 和 TwoDimensionalViewport

背景

表格是在应用程序中高效组织数据的有用工具。Flutter 的最新更新引入了 TwoDimensionalScrollView 小部件。9Pm28资讯网——每日最新资讯28at.com

TwoDimensionalScrollView 是一个小部件,它结合了 TwoDimensionalScrollable 和 TwoDimensionalViewport 在垂直和水平维度上创建内容的交互式滚动窗格,但直接使用它有点具有挑战性。9Pm28资讯网——每日最新资讯28at.com

下面是在 Flutter 中实现 2D ScrollView 的演示代码。9Pm28资讯网——每日最新资讯28at.com

介绍

Flutter 的预构建 widget 具有出色的性能,仅当子视图位于视图中时才延迟渲染子视图,从而提高了性能,但 Flutter 发布了一个新包 two_dimensional_scrollables 来实现在垂直轴和水平轴上滚动的 TableView。9Pm28资讯网——每日最新资讯28at.com

在本教程中,我们将探索这个包来实现一个非常简单的 Tableview,并了解如何自定义它。9Pm28资讯网——每日最新资讯28at.com

您可以在这里[1]找到完整的源代码。9Pm28资讯网——每日最新资讯28at.com

执行

添加依赖项

要添加依赖项,请首先打开 pubspec.yaml 文件,然后添加依赖项。9Pm28资讯网——每日最新资讯28at.com

dependencies:  two_dimensional_scrollables: <latest version>

将 TableView 添加到屏幕

添加 TableView 时,可以使用两个构造函数:9Pm28资讯网——每日最新资讯28at.com

  • TableView.list :这个与 Flutter 的 ListView 类似。它一次添加所有单元格,并且适用于较短的列表。
  • Tableview.builder :当视图进入视口时,它会延迟添加子项。非常适合您不想一次加载所有内容的较大列表!

让我们创建一个简单的 Tableview 来显示以下信息。9Pm28资讯网——每日最新资讯28at.com

class Employee { final String id; final String name; final String role; final String email;     Employee({         required this.id,         required this.name,         required this.role,         required this.email}); static get getEmployees{    return [      Employee(id: '1', name: 'John Doe', role: 'Manager', email: 'john@example.com'),      Employee(id: '2', name: 'Jane Smith', role: 'Developer', email: 'jane@example.com'),      Employee(id: '3', name: 'Mike Johnson', role: 'Designer', email: 'mike@example.com'),      Employee(id: '4', name: 'Emily Brown', role: 'HR Specialist',email: 'emily@example.com'),      Employee(id: '5', name: 'Alex Lee', role: 'Marketing Analyst', email: 'alex@example.com'),      Employee(id: '6', name: 'John Doe', role: 'Manager', email: 'john@example.com'),      Employee(id: '7', name: 'Jane Smith', role: 'Developer', email: 'jane@example.com'),      Employee(id: '8', name: 'Mike Johnson', role: 'Designer', email: 'mike@example.com'),      Employee(id: '9', name: 'Emily Brown', role: 'HR Specialist',email: 'emily@example.com'),      Employee(id: '10', name: 'Alex Lee', role: 'Marketing Analyst', email: 'alex@example.com'),     ];  }}

这是 TableView.builder 的基本示例代码。9Pm28资讯网——每日最新资讯28at.com

class TwoDimensionalScrollableDemo extends StatelessWidget {   TwoDimensionalScrollableDemo({super.key});final  List<Employee> employees = Employee.getEmployees;  @override  Widget build(BuildContext context) {    return Scaffold(      appBar: AppBar(        title: const Text("Table view Demo"),      ),      body: TableView.builder(          columnCount: 2,          rowCount: 11,          columnBuilder: buildTableSpan,          rowBuilder: buildTableSpan,          cellBuilder: (BuildContext context, TableVicinity vicinity) {            return Container(child: Center(child: addText(vicinity)));          }),    );  }  TableSpan buildTableSpan(int index){    return TableSpan(extent: FixedTableSpanExtent(50));  }  Widget addText(TableVicinity vicinity) {    if (vicinity.yIndex == 0 && vicinity.xIndex == 0) {      return const Text("Index");    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 1) {      return const Text("name");    } else if (vicinity.xIndex == 0) {      return Text(employees[vicinity.yIndex-1].id);    } else if (vicinity.xIndex == 1) {      return Text(employees[vicinity.yIndex-1].name);    }    return Text("");  }}

这对于几行代码来说已经相当不错了,让我们分解一下 TableView.builder 所需的参数。9Pm28资讯网——每日最新资讯28at.com

  • columnCount :该参数设置表中的列数。
  • rowCount :该参数设置表中的行数。
  • columnBuilder :它是一个帮助定义表中每列的布局和功能的函数。它接受一个整数作为参数,并返回一个 TableSpan ,它构造和配置列。
  • rowbuilder :与 columnBuilder 类似,此函数定义 TableView 中每行的布局和行为。
  • cellBuilder :它处理表中每个单元格的布局。它采用 TableVicinity 参数,其中包含特定单元格的行索引和列索引。这有助于您自定义表格中各个单元格的外观和行为。

运行上面的代码,您将看到以下输出。9Pm28资讯网——每日最新资讯28at.com

图片图片9Pm28资讯网——每日最新资讯28at.com

现在,让我们研究一下 TableView.builder 提供的功能!那么,让我们看看如何自定义和控制 TableView 并添加更多功能。9Pm28资讯网——每日最新资讯28at.com

TableSpan 表跨度

TableSpan 表示 TableView 中的一行或一列。9Pm28资讯网——每日最新资讯28at.com

添加边框

TableSpan buildTableSpan(int index) {  TableSpanDecoration decoration = const TableSpanDecoration(      border: TableSpanBorder(          trailing: BorderSide(color: Colors.black),          leading: BorderSide(color: Colors.black)));  return  TableSpan(      extent: const FixedTableSpanExtent(100),      foregroundDecoration: decoration);}

TableSpanDecoration 类用于指定 TableSpan 的装饰。我们可以通过 TableSpanBorder 类中的 border 参数为 TableSpan 添加边框,该类具有代表行左右边框和列上下边框的拖尾和前导属性。9Pm28资讯网——每日最新资讯28at.com

添加颜色

TableSpan buildTableSpan(int index) {  TableSpanDecoration decoration =  TableSpanDecoration(      color: index == 0 ? Colors.grey[300] : null,      border: const TableSpanBorder(          trailing: BorderSide(color: Colors.black),          leading: BorderSide(color: Colors.black)));  return  TableSpan(      extent: const FixedTableSpanExtent(100),      backgroundDecoration: decoration);}

TableSpanDecoration 中的 color 属性用于设置 TableSpan 的颜色。9Pm28资讯网——每日最新资讯28at.com

运行代码,输出将如下所示9Pm28资讯网——每日最新资讯28at.com

图片图片9Pm28资讯网——每日最新资讯28at.com

因为9Pm28资讯网——每日最新资讯28at.com

  • 在 TableView 中,装饰按特定顺序绘制。
  • 首先绘制 mainAxis 的 backgroundDecoration (作为主轴的行或列)。
  • 然后,绘制其他轴上的装饰。
  • 接下来,绘制跨度内的各个单元格内容。
  • 最后,任何指定的 foregroundDecoration 都会绘制在内容之上。

这里默认的轴是 Axis.vertical ,所以,先绘制列,然后绘制行,边框与行装饰重叠,所以,让我们为前景装饰添加边框。9Pm28资讯网——每日最新资讯28at.com

TableSpan buildTableSpan(int index) {  TableSpanDecoration foreGroundDecoration = const TableSpanDecoration(      border: TableSpanBorder(          trailing: BorderSide(color: Colors.black),          leading: BorderSide(color: Colors.black)));  TableSpanDecoration backGroundDecoration = TableSpanDecoration(    color: index == 0 ? Colors.grey[300] : null,  );  return TableSpan(      extent: const FixedTableSpanExtent(100),      backgroundDecoration: backGroundDecoration,      foregroundDecoration: foreGroundDecoration);}

在前景装饰中添加边框可确保其呈现在 TableView 中单元格内容的顶部。9Pm28资讯网——每日最新资讯28at.com

图片图片9Pm28资讯网——每日最新资讯28at.com

TableSpan.extent

它表示行的高度和列的宽度,TableSpanExtent 有四种类型。9Pm28资讯网——每日最新资讯28at.com

1.FixedTableSpanExtent

具有固定[像素]的跨度。9Pm28资讯网——每日最新资讯28at.com

extent: const FixedTableSpanExtent(50),

图片图片9Pm28资讯网——每日最新资讯28at.com

2.FractionTableSpanExtent

它将跨度范围指定为视口范围的一部分。它与 Expanded 小部件相同,根据提供的分数占用空间。9Pm28资讯网——每日最新资讯28at.com

extent: const FractionalTableSpanExtent(0.5),

图片图片9Pm28资讯网——每日最新资讯28at.com

3.RemainingTableSpanExtent

它指定跨度应占据视口中的剩余空间。9Pm28资讯网——每日最新资讯28at.com

TableSpan buildColumnSpan(int index) {  TableSpanDecoration decoration =  const TableSpanDecoration(      border: TableSpanBorder(          trailing: BorderSide(color: Colors.black),          leading: BorderSide(color: Colors.black)));  return TableSpan(      extent: index==0? FixedTableSpanExtent(100):RemainingTableSpanExtent(), backgroundDecoration: decoration);}

图片图片9Pm28资讯网——每日最新资讯28at.com

4.CombiningTableSpanExtent

它以两个范围作为参数,并通过组合器函数运行这两个范围的结果。9Pm28资讯网——每日最新资讯28at.com

TableSpan buildRowSpan(int index) {    TableSpanExtent extent1 = FixedTableSpanExtent(100);    TableSpanExtent extent2 = FixedTableSpanExtent(100);    double combiner(double value1, double value2) {      return value1 + value2;    }    TableSpanDecoration foreGroundDecoration = const TableSpanDecoration(        border: TableSpanBorder(            trailing: BorderSide(color: Colors.black),            leading: BorderSide(color: Colors.black)));    TableSpanDecoration backGroundDecoration = TableSpanDecoration(      color: index == 0 ? Colors.grey[300] : null,    );    if (index == 1) {      return TableSpan(          extent: CombiningTableSpanExtent(extent1, extent2, combiner),          backgroundDecoration: backGroundDecoration,          foregroundDecoration: foreGroundDecoration);    }    return TableSpan(        extent: const FixedTableSpanExtent(100),        backgroundDecoration: backGroundDecoration,        foregroundDecoration: foreGroundDecoration);  }

图片图片9Pm28资讯网——每日最新资讯28at.com

当鼠标指针(按下或不按下按钮)进入此跨度描述的行或列时触发。9Pm28资讯网——每日最新资讯28at.com

void Function(PointerEnterEvent)? onEnter

void Function(PointerExitEvent)? onExit

当鼠标指针(按下或未按下按钮)退出此跨度描述的行或列时,它会触发。9Pm28资讯网——每日最新资讯28at.com

void Function(PointerExitEvent)? onExit

recognizerFactories

recognizerFactories: <Type, GestureRecognizerFactory>{  TapGestureRecognizer:  GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(        () => TapGestureRecognizer(),        (TapGestureRecognizer t) {          t.notallow=(TapDownDetails tapdownDetails){            print(tapdownDetails.localPosition);          };          t.notallow=(TapUpDetails tapupDetails){            print(tapupDetails.localPosition);          };        }     ),},

recognizerFactories 是一个映射,其中键是手势类型,值是 GestureRecognizerFactory 的实例。9Pm28资讯网——每日最新资讯28at.com

GestureRecognizerFactoryWithHandlers 有两个参数。调用时返回 TapGestureRecognizer 实例的函数和初始化 TapGestureRecognizer 并设置事件处理程序以处理特定事件详细信息的回调函数。9Pm28资讯网——每日最新资讯28at.com

添加填充

padding 属性用于为每行和每列添加填充。9Pm28资讯网——每日最新资讯28at.com

padding: TableSpanPadding(leading: 10),

向 UI 添加更多列和行

让我们在 TableView 中显示来自 Employee 类的更多数据,例如 email 和 role 。9Pm28资讯网——每日最新资讯28at.com

Widget addText(TableVicinity vicinity) {    if (vicinity.yIndex == 0 && vicinity.xIndex == 0) {      return const Text("Index");    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 1) {      return const Text("name");    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 2) {      return const Text("Email");    } else if (vicinity.yIndex == 0 && vicinity.xIndex == 3) {      return const Text("Role");    } else if (vicinity.xIndex == 0) {      return Text(employees[vicinity.yIndex - 1].id);    } else if (vicinity.xIndex == 1) {      return Text(employees[vicinity.yIndex - 1].name);    } else if (vicinity.xIndex == 2) {      return Text(employees[vicinity.yIndex - 1].email);    } else if (vicinity.xIndex == 3) {      return Text(employees[vicinity.yIndex - 1].role);    }    return Text("");  }...      body: TableView.builder(          mainAxis: Axis.horizontal,          columnCount: 4,          rowCount: 21,          columnBuilder: buildColumnSpan,          rowBuilder: buildTableSpan,          cellBuilder: (BuildContext context, TableVicinity vicinity) {            return Center(child: addText(vicinity));          }),...TableSpan buildColumnSpan(int index) {  TableSpanDecoration decoration = const TableSpanDecoration(      border: TableSpanBorder(          trailing: BorderSide(color: Colors.black),          leading: BorderSide(color: Colors.black)));  if (index == 2) {    return TableSpan(      extent: const RemainingTableSpanExtent(),      backgroundDecoration: decoration,    );  } else if (index == 3) {    return TableSpan(      extent: const FractionalTableSpanExtent(0.5),      backgroundDecoration: decoration,    );  }  return TableSpan(      extent: FixedTableSpanExtent(100), backgroundDecoration: decoration);}

输出是:9Pm28资讯网——每日最新资讯28at.com

图片图片9Pm28资讯网——每日最新资讯28at.com

固定行和列

固定持续出现在 TableView 视口边缘的特定数量的行和列。9Pm28资讯网——每日最新资讯28at.com

TableView.builder(...    pinnedRowCount: 1,    pinnedColumnCount: 1,   ),

图片图片9Pm28资讯网——每日最新资讯28at.com

滚动细节

ScrollableDetail 允许对小部件的垂直和水平滚动行为进行特定配置。9Pm28资讯网——每日最新资讯28at.com

verticalDetails: ScrollableDetails.vertical(  reverse: true,  controller: verticalController,  physics: const AlwaysScrollableScrollPhysics(),  decorationClipBehavior: Clip.hardEdge),

ScrollableDetails 中的 verticalDetails 允许对小部件的垂直滚动行为进行特定配置,它封装了各种属性。9Pm28资讯网——每日最新资讯28at.com

verticalDetails: ScrollableDetails.vertical(  reverse: true,  controller: verticalController,  physics: const AlwaysScrollableScrollPhysics(),  decorationClipBehavior: Clip.hardEdge,)

以下是属性的详细说明:9Pm28资讯网——每日最新资讯28at.com

  • reverse :当设置为 true 时,小部件内的内容向相反方向滚动。
  • controller :指定用于管理和控制滚动行为的 ScrollController 。它允许您滚动到特定位置或收听滚动偏移量的变化。
  • physics :确定滚动物理的行为。
  • decorationClipBehavior :指定可滚动区域装饰的剪切行为

cacheExtent 缓存范围

cacheExtent: 200,

与ListView类似, cacheExtent 是在进入屏幕可见部分之前绘制的区域的大小。9Pm28资讯网——每日最新资讯28at.com

DiagonalDragBehavior 对角线拖动行为

该枚举允许开发人员指定如何使用 kTouchSlop 处理对角滚动。9Pm28资讯网——每日最新资讯28at.com

结论

在本教程中,我们学习了如何使用 Flutter 中的 two_dimensional_scrollable 实现 Flutter 中的 tableView,我们可以用它做更多的事情并使用它添加更多功能。这是我对 Flutter 中 TableView 的一个小介绍。9Pm28资讯网——每日最新资讯28at.com

图片翻译自:https://blog.canopas.com/how-to-implement-2d-scrollable-tableview-in-flutter-a8b0fe703614图片9Pm28资讯网——每日最新资讯28at.com

参考资料:

[1]这里: https://gist.github.com/cp-sneha-s/d2375b2a624f5650fa3836a84805b15f9Pm28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-100463-0.html如何在 Flutter 中实现 2D 可滚动的表格,探索 Flutter 中的二维可滚动项,表格解决方案

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 一文带您理解Python的map/filter/reduce

下一篇: 基于Rspack实现大仓应用构建提效实践

标签:
  • 热门焦点
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • 三言两语说透设计模式的艺术-单例模式

    写在前面单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少
  • 三言两语说透柯里化和反柯里化

    JavaScript中的柯里化(Currying)和反柯里化(Uncurrying)是两种很有用的技术,可以帮助我们写出更加优雅、泛用的函数。本文将首先介绍柯里化和反柯里化的概念、实现原理和应用
  • 电视息屏休眠仍有网络上传 爱奇艺被质疑“薅消费者羊毛”

    记者丨宁晓敏 见习生丨汗青出品丨鳌头财经(theSankei) 前不久,爱奇艺发布了一份亮眼的一季报,不仅营收和会员营收创造历史最佳表现,其运营利润也连续6个月实现增长。自去年年初
  • “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 签约井川里予、何丹彤,单视频点赞近千万,MCN黑马永恒文希快速崛起!

    来源:视听观察永恒文希传媒作为一家MCN公司,说起它的名字来,可能大家会觉得有点儿陌生,但是说出来下面一串的名字之后,或许大家就会感到震惊,原来这么多网红,都签约这家公司了。根
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • iQOO 11S评测:行业唯一的200W标准版旗舰

    【Techweb评测】去年底,iQOO推出了“电竞旗舰”iQOO 11系列,作为一款性能强机,该机不仅全球首发2K 144Hz E6全感屏,搭载了第二代骁龙8平台及144Hz电竞
  • iQOO Neo8 Pro真机谍照曝光:天玑9200+和V1+旗舰双芯加持

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
Top