Flutter表格视图插件flexible_scrollable_table_view的使用
Flutter表格视图插件flexible_scrollable_table_view的使用
在本教程中,我们将详细介绍如何使用flexible_scrollable_table_view
插件来创建一个灵活且可滚动的表格视图。我们将通过一个完整的示例来展示如何实现这一功能。
使用方法
Column(children: [
FlexibleTableHeader<T>(
dataSource,
rowBuilder: rowBuilder,
),
Expanded(
child: FlexibleTableContent<T>(
dataSource,
rowBuilder: rowBuilder,
),
),
]);
其中
<T>
为表格每一行的数据类型。dataSource
为表格数据源,其类型为FlexibleTableDataSource<T>
。它是ChangeNotifier
的子类,并实现了ValueListenable<List<T>>
,类似ValueNotifier<T>
。rowBuilder
为表行构建代理类。在FlexibleTableHeader<T>
中为FlexibleTableHeaderRowBuilderMixin<T>
类型,在FlexibleTableContent<T>
中为FlexibleTableInfoRowBuilderMixin<T>
类型。
完整示例代码
import 'dart:async';
import 'dart:math';
import 'package:flexible_scrollable_table_view/flexible_scrollable_table_view.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TableHorizontalScrollMixin {
late FlexibleTableDataSource<StudentBean> dataSource;
late FlexibleTableRowBuilderMixin<StudentBean> rowBuilder;
late SynchronizedScrollMixin scrollMixin;
late AdaptedGroup group;
late ValueNotifier<String> randomName;
[@override](/user/override)
void initState() {
super.initState();
dataSource = FlexibleTableDataSource();
scrollMixin = SynchronizedScrollController();
group = AdaptedGroup();
randomName = ValueNotifier('');
rowBuilder = DefaultRowBuilder(
this,
leftPinnedColumns: {
const StudentIdColumn()
// 设置列宽为固定宽度
.appointWidth(const FixedWidth(100)),
},
scrollableColumns: {
StudentNameColumn(
randomName: randomName,
)
// 设置列的宽度根据其内容自动变化
.appointWidth(AdaptedWidth<StudentBean>(group)),
const StudentAgeColumn()
// 给列头添加点击排序的功能
.withSortByPressColumnHeader((column, a, b) => a.age.compareTo(b.age))
// 设置列宽为父容器宽度的 0.5 倍
.appointWidth(ProportionalWidth(0.5)),
const StudentGenderColumn()
// 给列信息项添加点击事件
.whenInfoClicked((column, arguments, context) {
debugPrint('点击了[${column.id}]列的第[${arguments.dataIndex}]项的数据[${arguments.data.gender}]');
}).appointWidth(const FixedWidth(60)),
},
)
// 给行设置固定的高度
.appointHeight(const FixedHeight(headerHeight: 48, infoHeight: 150))
// 给行设置装饰
.withDecoration(
infoRowDecoration: (arguments) {
return BoxDecoration(
color: arguments.dataIndex.isEven ? Colors.blue.shade50 : Colors.blue.shade100,
);
},
);
refreshName();
refreshData();
}
[@override](/user/override)
void dispose() {
super.dispose();
timer.cancel();
randomName.dispose();
group.dispose();
scrollMixin.dispose();
}
late Timer timer;
void refreshName() {
timer = Timer.periodic(const Duration(seconds: 1), (timer) {
randomName.value = randomNames.first;
});
}
[@override](/user/override)
ScrollController createScrollController() {
return scrollMixin;
}
[@override](/user/override)
void destroyScrollController(ScrollController controller) {}
void refreshData() {
final Random random = Random.secure();
final List<String> names = List.of(randomNames);
dataSource.value = names
.map<StudentBean>(
(e) => StudentBean(
id: int.parse(e.hashCode.toString().substring(0, 3)),
name: e,
age: random.nextInt(3) + 12,
gender: random.nextBool() ? '男' : '女',
),
)
.toList(growable: false);
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
actions: [
IconButton(
onPressed: refreshData,
icon: const Icon(Icons.refresh_rounded),
),
],
),
body: Column(children: [
Material(
elevation: 4,
color: Colors.white,
child: FlexibleTableHeader<StudentBean>(dataSource, rowBuilder: rowBuilder),
),
Expanded(
child: FlexibleTableContent<StudentBean>(dataSource, rowBuilder: rowBuilder),
),
]),
);
}
}
class StudentIdColumn extends AbsFlexibleTableColumn<StudentBean> {
const StudentIdColumn() : super('学号');
[@override](/user/override)
Widget buildHeaderCell(TableBuildArgumentsMixin<StudentBean> arguments) {
return Align(
alignment: Alignment.centerLeft,
child: Text(id.toString()),
);
}
[@override](/user/override)
Widget buildInfoCell(TableInfoRowArgumentsMixin<StudentBean> arguments) {
return Align(
alignment: Alignment.centerLeft,
child: Text(
arguments.data.id.toString(),
),
);
}
}
class StudentNameColumn extends AbsFlexibleTableColumn<StudentBean> {
const StudentNameColumn({
required this.randomName,
}) : super('姓名');
final ValueNotifier<String> randomName;
[@override](/user/override)
Widget buildHeaderCell(TableBuildArgumentsMixin<StudentBean> arguments) {
return Center(child: Text(id.toString()));
}
[@override](/user/override)
Widget buildInfoCell(TableInfoRowArgumentsMixin<StudentBean> arguments) {
final Widget child;
if (arguments.dataIndex == 3) {
// 将3号下标的内容替换为会变化的文字
child = ValueListenableBuilder<String>(
valueListenable: randomName,
builder: (context, value, child) => Text(value),
);
} else {
child = Text(
arguments.data.name,
);
}
return ColoredBox(
color: arguments.dataIndex.isOdd ? Colors.pinkAccent : Colors.purple,
child: Align(
alignment: Alignment.centerRight,
child: child,
),
);
}
}
class StudentAgeColumn extends AbsFlexibleTableColumn<StudentBean> {
const StudentAgeColumn() : super('年龄');
[@override](/user/override)
Widget buildHeaderCell(TableBuildArgumentsMixin<StudentBean> arguments) {
return Center(child: Text(id.toString()));
}
[@override](/user/override)
Widget buildInfoCell(TableInfoRowArgumentsMixin<StudentBean> arguments) {
return Center(
child: Text(
arguments.data.age.toString(),
),
);
}
}
class StudentGenderColumn extends AbsFlexibleTableColumn<StudentBean> {
const StudentGenderColumn() : super('性别');
[@override](/user/override)
Widget buildHeaderCell(TableBuildArgumentsMixin<StudentBean> arguments) {
return Center(child: Text(id.toString()));
}
[@override](/user/override)
Widget buildInfoCell(TableInfoRowArgumentsMixin<StudentBean> arguments) {
return Center(
child: Text(
arguments.data.gender,
),
);
}
}
class StudentBean {
const StudentBean({
required this.id,
required this.name,
required this.age,
required this.gender,
});
final int id;
final String name;
final int age;
final String gender;
[@override](/user/override)
bool operator ==(Object other) =>
identical(this, other) ||
other is StudentBean &&
runtimeType == other.runtimeType &&
id == other.id &&
name == other.name &&
age == other.age &&
gender == other.gender;
[@override](/user/override)
int get hashCode => id.hashCode ^ name.hashCode ^ age.hashCode ^ gender.hashCode;
}
List<String> get randomNames => [
'Zelda',
'Sebastian',
'Trista',
'Holy',
'Joyce',
'Kirstyn',
'Dale',
'Walter',
'Immortal',
'Garret',
'Jillian',
'Timothea',
'Quinlan',
'Philomena',
'Logan',
'Fairy',
'Gazelle',
'Lorelei',
'Haley',
'Miriam',
'Ian',
'Beautiful',
'Audrey',
'Harmony',
'Quintana',
'Russell',
'Patience',
'Edric',
'Rosalind',
'Serpent',
]..shuffle();
更多关于Flutter表格视图插件flexible_scrollable_table_view的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter表格视图插件flexible_scrollable_table_view的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flexible_scrollable_table_view
是一个用于 Flutter 的表格视图插件,它允许你创建可滚动的、灵活的表格。这个插件非常适合用于展示大量数据,并且支持自定义表头、行、列等。
安装
首先,你需要在 pubspec.yaml
文件中添加依赖:
dependencies:
flexible_scrollable_table_view: ^latest_version
然后运行 flutter pub get
来安装依赖。
基本用法
以下是一个简单的示例,展示了如何使用 flexible_scrollable_table_view
来创建一个基本的表格:
import 'package:flutter/material.dart';
import 'package:flexible_scrollable_table_view/flexible_scrollable_table_view.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flexible Scrollable Table View Example')),
body: TableExample(),
),
);
}
}
class TableExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlexibleScrollableTableView(
columns: [
TableViewColumn(label: 'ID', width: 100),
TableViewColumn(label: 'Name', width: 150),
TableViewColumn(label: 'Age', width: 100),
TableViewColumn(label: 'City', width: 200),
],
rows: List.generate(100, (index) {
return TableViewRow(
cells: [
TableViewCell(child: Text('${index + 1}')),
TableViewCell(child: Text('User $index')),
TableViewCell(child: Text('${20 + index}')),
TableViewCell(child: Text('City $index')),
],
);
}),
);
}
}
主要功能
-
自定义列宽和行高:
- 你可以通过
TableViewColumn
的width
属性来设置列宽。 - 通过
TableViewRow
的height
属性来设置行高。
- 你可以通过
-
固定表头:
FlexibleScrollableTableView
默认支持固定表头,当表格内容滚动时,表头会保持在顶部。
-
自定义单元格内容:
- 你可以通过
TableViewCell
的child
属性来设置单元格内容,支持任何Widget
。
- 你可以通过
-
分页加载:
- 你可以通过
FlexibleScrollableTableView
的onLoadMore
回调来实现分页加载功能。
- 你可以通过
-
自定义样式:
- 你可以通过
FlexibleScrollableTableView
的headerStyle
和cellStyle
来自定义表头和单元格的样式。
- 你可以通过
高级用法
1. 分页加载
FlexibleScrollableTableView(
columns: [
TableViewColumn(label: 'ID', width: 100),
TableViewColumn(label: 'Name', width: 150),
],
rows: List.generate(50, (index) {
return TableViewRow(
cells: [
TableViewCell(child: Text('${index + 1}')),
TableViewCell(child: Text('User $index')),
],
);
}),
onLoadMore: () {
// 加载更多数据
},
)
2. 自定义样式
FlexibleScrollableTableView(
columns: [
TableViewColumn(label: 'ID', width: 100),
TableViewColumn(label: 'Name', width: 150),
],
rows: List.generate(50, (index) {
return TableViewRow(
cells: [
TableViewCell(child: Text('${index + 1}')),
TableViewCell(child: Text('User $index')),
],
);
}),
headerStyle: TableViewHeaderStyle(
backgroundColor: Colors.blue,
textStyle: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
),
cellStyle: TableViewCellStyle(
backgroundColor: Colors.white,
textStyle: TextStyle(color: Colors.black),
),
)