flutter - 如何在颤动的可编辑表中添加搜索和排序?
问题描述
由于我是 Flutter 的新手,所以我找不到如何在 Flutter 中的可编辑数据表上添加搜索和排序的解决方案。为了创建一个可编辑的数据表,我editable: ^1.1.1
在我的项目中使用包。我怎样才能做到这一点?请任何人帮助我!
下面是我的代码。
可编辑数据.dart
import 'package:editable/editable.dart';
import 'package:flutter/material.dart';
class TablePage extends StatefulWidget {
@override
_TablePageState createState() => _TablePageState();
}
class _TablePageState extends State<TablePage> {
final _editableKey = GlobalKey<EditableState>();
List rows = [
{'name': 'Abhi', 'age': '23'},
{'name': 'Sipun', 'age': '19'},
{'name': 'Lipun', 'age': '12'},
];
List headers = [
{'title': 'Name', 'index': 1, 'key':'name'},
{'title': 'Age', 'index' : 2, 'key': 'age'},
];
void _printEditedRows() {
List editedRows = _editableKey.currentState.editedRows;
print(editedRows);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
Padding(
padding: const EdgeInsets.all(8.0),
child: FlatButton(
onPressed: () => _printEditedRows(),
child: Text('Print Edited Rows',
style: TextStyle(fontWeight: FontWeight.bold))),
)
],
),
body: Padding(
padding: const EdgeInsets.all(100.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Editable(
key: _editableKey,
columns: headers,
rows: rows,
tdStyle: TextStyle(fontSize: 20),
showSaveIcon: false,
borderColor: Colors.grey.shade300,
),
],
),
),
);
}
}
解决方案
我查看了您的问题,但在我更改其行属性时拒绝更新表格内容的可编辑包遇到了困难。所以,我想,用以下基本块来实现你的要求有多难?
- 表格的Flutter DataTable,
- 用于状态管理的flutter_hooks 包和hooks_riverpod 包,
- 不可变模型的冻结包,
- 模糊搜索的模糊包。
所以,这是我在 140 行代码中的解决方案。
1.成员模型类
我们保持它非常基本,只是添加一个uid
用于适当的状态管理。
@freezed
abstract class Member with _$Member {
factory Member({String uid, String name, int age}) = _Member;
}
使用Mockaroo生成的一些测试数据:
final List<Member> testData = [
Member(name: "Adrian Andreuzzi", uid: "gi768157", age: 84),
Member(name: "Angil Aglione", uid: "uc772005", age: 26),
Member(name: "Bald Geertsen", uid: "ng269401", age: 99),
Member(name: "Bree Minshull", uid: "rg692522", age: 10),
Member(name: "Daniella Giacobini", uid: "tk828689", age: 94),
Member(name: "Darn Kennion", uid: "zm299734", age: 44),
Member(name: "Derron Rault", uid: "ax854756", age: 21),
Member(name: "Ester Stoffersen", uid: "ia343485", age: 92),
Member(name: "Fulvia Maher", uid: "hy669111", age: 43),
Member(name: "Glennie Rogers", uid: "ma744931", age: 88),
Member(name: "Jannelle Rubinsztein", uid: "je802620", age: 44),
Member(name: "Jerrylee MacConnell", uid: "ad466446", age: 85),
Member(name: "Nappy Dewan", uid: "zd804411", age: 55),
Member(name: "Oberon Pudge", uid: "mz474307", age: 08),
Member(name: "Petunia Dany", uid: "pt098116", age: 20),
Member(name: "Rodolfo Gipp", uid: "cs063868", age: 61),
Member(name: "Rolando Teese", uid: "mq696713", age: 54),
Member(name: "Tiena Strute", uid: "rj867066", age: 14),
Member(name: "Tove McDonell", uid: "sk682172", age: 36),
Member(name: "Verney Bryenton", uid: "he816728", age: 66),
];
2.状态管理
2.1 会员提供者
此提供程序用作内存中的持久性。您必须将其连接到本地和/或远程数据源。
它提供了成员以及更新成员的方法。可以使用相同的方法添加新成员,使用新的uid
.
final membersProvider = StateNotifierProvider<MembersStateNotifier>(
(ref) => MembersStateNotifier(),
);
class MembersStateNotifier extends StateNotifier<List<Member>> {
MembersStateNotifier([List<Member> state]) : super(state ?? testData);
void update(Member updatedMember) {
state = [
...state.where((member) => member.uid != updatedMember.uid),
updatedMember,
].sorted((a, b) => a.name.compareTo(b.name));
print(state.where((item) => item.uid == updatedMember.uid));
}
}
2.2 搜索引擎提供商
它提供了每次更新成员列表时都会重置的模糊搜索引擎。这也是我定义搜索引擎选项的地方,例如使用哪些键和权重。
final searchEngineProvider = StateNotifierProvider<SearchEngineNotifier>((ref) {
final members = ref.watch(membersProvider.state);
return SearchEngineNotifier(members);
});
class SearchEngineNotifier extends StateNotifier<Fuzzy<Member>> {
SearchEngineNotifier(List<Member> members) : super(null) {
_resetEngine(members);
}
void _resetEngine(List<Member> members) {
print('RESET $members');
state = Fuzzy<Member>(
members,
options: FuzzyOptions(
keys: [
WeightedKey(getter: (item) => item.name, weight: 1, name: 'name'),
],
threshold: .6,
shouldSort: true,
),
);
}
}
2.3 搜索词提供者
当前搜索词的基本提供者。
final searchTermProvider = StateProvider<String>((ref) => '');
2.4 过滤成员提供者
此 Providers 组合所有提供程序以提供过滤后的成员列表:
searchTermProvider
membersProvider
searchEngineProvider
请注意,我阅读了StateNotifier 类中的membersProvider
and searchEngineProvider
,以便仅在更改搜索词时才获得新的 StateNotifier ,而不是在编辑成员时。
final filteredMembersProvider = StateNotifierProvider<FilteredMembersNotifier>(
(ref) {
final searchTerm = ref.watch(searchTermProvider).state;
return FilteredMembersNotifier(searchTerm, ref.read);
},
);
class FilteredMembersNotifier extends StateNotifier<List<Member>> {
final Reader read;
final String searchTerm;
FilteredMembersNotifier(this.searchTerm, this.read) : super(null) {
state = searchTerm.isEmpty
? read(membersProvider.state)
: read(searchEngineProvider)
.state
.search(searchTerm)
.map((result) => result.item)
.toList();
print('STATE: $state');
}
}
小部件
我们的基本应用程序将使用三个小部件:
MembersPage
, 我们的脚手架SearchBox
MembersDataTable
虽然MembersPage
是访问 Providers 的 HookWidget,但两者SearchBox
都是MembersDataTable
非常基本的 StatelessWidget。
3.1 会员页面
状态管理:
- 从中获取过滤后的成员
filteredMembersProvider
, - 更改更新
searchTermProvider
,SearchBox
- 更改更新
membersProvider
,MembersDataTable
class MembersPage extends HookWidget {
@override
Widget build(BuildContext context) {
final _members = useProvider(filteredMembersProvider.state);
return Scaffold(
appBar: AppBar(
title: Text('Members'),
actions: [
Padding(
padding: EdgeInsets.all(8.0),
child: SearchBox(
onSearch: (searchTerm) =>
context.read(searchTermProvider).state = searchTerm),
),
],
),
body: Center(
child: _members.isEmpty
? Text('No members found.')
: SingleChildScrollView(
child: MembersDataTable(
members: _members,
onChanged: context.read(membersProvider).update,
),
),
),
);
}
}
3.2 搜索框
class SearchBox extends StatelessWidget {
final ValueChanged<String> onSearch;
const SearchBox({
Key key,
@required this.onSearch,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: 150,
child: TextFormField(
initialValue: '',
style: TextStyle(color: Colors.white),
cursorColor: Colors.white,
decoration: InputDecoration(
hintText: "Search",
hintStyle: TextStyle(fontSize: 16, color: Colors.white),
isDense: true,
suffixIcon: Icon(Icons.search, color: Colors.white),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(
color: Colors.white,
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide(style: BorderStyle.none),
),
filled: true,
fillColor: Colors.lightBlue.shade200,
),
onChanged: onSearch,
),
);
}
}
3.3 成员数据表
class MembersDataTable extends StatelessWidget {
final List<Member> members;
final ValueChanged<Member> onChanged;
const MembersDataTable({
Key key,
this.members,
this.onChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return DataTable(
columns: [
DataColumn(label: Text('Name')),
DataColumn(label: Text('Age')),
],
rows: members.map(
(member) {
return DataRow(
cells: [
DataCell(
TextFormField(
controller: TextEditingController(text: member.name),
decoration: InputDecoration(border: InputBorder.none),
onChanged: (value) =>
onChanged?.call(member.copyWith(name: value)),
),
),
DataCell(
TextFormField(
controller:
TextEditingController(text: member.age.toString()),
decoration: InputDecoration(border: InputBorder.none),
onChanged: (value) =>
onChanged?.call(member.copyWith(age: int.parse(value))),
),
),
],
);
},
).toList(),
);
}
}
4. 申请
void main() {
runApp(
ProviderScope(
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Members DataTable',
home: MembersPage(),
),
),
);
}
缺少功能
当然,这个解决方案还远未完成。这更像是一次有趣的探索练习。
以下是缺失功能的非详尽列表:
- 远程和/或本地数据库持久性
- 添加/删除成员的可能性
- 可以对表格的列进行排序
瞧!如果您发现任何问题或改进此基本解决方案的方法,请告诉我,我将更新我的答案。
推荐阅读
- javascript - 返回前一天的时刻
- python-3.x - 获取 Keras 变量列表
- jquery - JQuery:遍历表并计算每个表中的行数
- python - 在 Python 中使用 for 循环的 2D 网格
- php - nginx 错误 GET //error-404 HTTP/1.1" 499 0 "-" "-"
- matlab - 我在 Matlab 中做错了什么?
- tree - R:从 h2o.download_mojo() 绘制树,一直遇到错误
- powershell - 如何在 Powershell Menu 中创建 Menu 洞察力
- excel - excel统计出现或延迟值
- c - 用 C 读写文件