Gra*_*gus 3 mobile search flutter flutter-layout
我为我的列表创建了一个简单的搜索栏DataTable,但问题是我无法仅返回我搜索的项目,而是得到空字段和我搜索的项目。我已经尝试了各种方法,但我得到的错误是我需要的行和我需要的列一样多,所以这是现在我让它工作的唯一方法。
但我想让它变成这样:
这是代码:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'models/vehicle.dart';
import 'services/vehicle_api.dart';
import 'models/vehicle_data_provider.dart';
class VehicleList extends StatefulWidget {
@override
_VehicleList createState() => _VehicleList();
}
class _VehicleList extends State<VehicleList> {
TextEditingController controller = TextEditingController();
String _searchResult = '';
_getPosts() async {
HomePageProvider provider =
Provider.of<HomePageProvider>(context, listen: false);
var postsResponse = await fetchVehicles();
if (postsResponse.isSuccessful) {
provider.setPostsList(postsResponse.data, notify: false);
} else {
provider.mergePostsList(
postsResponse.data,
);
}
provider.setIsHomePageProcessing(false);
}
@override
void initState() {
_getPosts();
super.initState();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Card(
child: new ListTile(
leading: new Icon(Icons.search),
title: new TextField(
controller: controller,
decoration: new InputDecoration(
hintText: 'Search', border: InputBorder.none),
onChanged: (value) {
setState(() {
_searchResult = value;
});
}),
trailing: new IconButton(
icon: new Icon(Icons.cancel),
onPressed: () {
setState(() {
controller.clear();
_searchResult = '';
});
},
),
),
),
Consumer<HomePageProvider>(
builder: (context, vehicleData, child) {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.all(
Radius.circular(12.0),
),
),
child: SingleChildScrollView(
child: DataTable(
columnSpacing: 30,
columns: <DataColumn>[
DataColumn(
numeric: false,
label: Text(
'Friendly Name',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Licence Plate',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
DataColumn(
label: Text(
'Delete',
style: TextStyle(fontStyle: FontStyle.italic),
),
),
],
rows: List.generate(
vehicleData.postsList.length,
(index) {
VehicleData post = vehicleData.getPostByIndex(index);
return post.licencePlate
.toLowerCase()
.contains(_searchResult) ||
'${post.model}'
.toLowerCase()
.contains(_searchResult) ||
'${post.make}'
.toLowerCase()
.contains(_searchResult) ||
post.type
.toLowerCase()
.contains(_searchResult)
? DataRow(
cells: <DataCell>[
DataCell(
Text('${post.friendlyName}'),
),
DataCell(
Text('${post.licencePlate}'),
),
DataCell(
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
vehicleData.deletePost(post);
},
),
),
],
)
: DataRow(
/// This is the part where I return empty rows with one row with the search bar results, so I assume this must me changed
cells: <DataCell>[
DataCell(Text('')),
DataCell(Text('')),
DataCell(Text('')),
],
);
},
),
),
),
),
],
);
},
),
],
);
}
}
Run Code Online (Sandbox Code Playgroud)
这题好像想不通 先谢谢您的帮助!
好吧,在您发表评论后,我终于按照我认为您想要的方式工作了。这个想法是使用两个列表而不是一个列表,并且List.generate由于该空行而不使用该方法。当您更改值时,您可以使用列表中的原始值_searchResult过滤列表。userFilteredusers
我使用 DataTable 的 flutter 示例进行了这些编辑,并且它有效:
\nimport \'package:flutter/material.dart\';\n\nvoid main() => runApp(const MyApp());\n\n/// This is the main application widget.\nclass MyApp extends StatelessWidget {\n const MyApp({Key key}) : super(key: key);\n\n static const String _title = \'Flutter Code Sample\';\n\n @override\n Widget build(BuildContext context) {\n return MaterialApp(\n title: _title,\n home: Scaffold(\n appBar: AppBar(title: const Text(_title)),\n body: MyStatelessWidget(),\n ),\n );\n }\n}\n\n\nclass User{\n String name;\n int age;\n String role;\n\n User({this.name, this.age, this.role});\n}\n\n/// This is the stateless widget that the main application instantiates.\nclass MyStatelessWidget extends StatefulWidget {\n MyStatelessWidget({Key key}) : super(key: key);\n\n @override\n _MyStatelessWidgetState createState() => _MyStatelessWidgetState();\n}\n\nclass _MyStatelessWidgetState extends State<MyStatelessWidget> {\n List<User> users = [User(name: "Sarah", age: 19, role: "Student"), User(name: "Janine", age: 43, role: "Professor")];\n List<User> usersFiltered = [];\n TextEditingController controller = TextEditingController();\n String _searchResult = \'\';\n\n @override\n void initState() {\n super.initState();\n usersFiltered = users;\n }\n\n @override\n Widget build(BuildContext context) {\n return Column(\n children: [\n Card(\n child: new ListTile(\n leading: new Icon(Icons.search),\n title: new TextField(\n controller: controller,\n decoration: new InputDecoration(\n hintText: \'Search\', border: InputBorder.none),\n onChanged: (value) {\n setState(() {\n _searchResult = value;\n usersFiltered = users.where((user) => user.name.contains(_searchResult) || user.role.contains(_searchResult)).toList();\n });\n }),\n trailing: new IconButton(\n icon: new Icon(Icons.cancel),\n onPressed: () {\n setState(() {\n controller.clear();\n _searchResult = \'\';\n usersFiltered = users;\n });\n },\n ),\n ),\n ),\n DataTable(\n columns: const <DataColumn>[\n DataColumn(\n label: Text(\n \'Name\',\n style: TextStyle(fontStyle: FontStyle.italic),\n ),\n ),\n DataColumn(\n label: Text(\n \'Age\',\n style: TextStyle(fontStyle: FontStyle.italic),\n ),\n ),\n DataColumn(\n label: Text(\n \'Role\',\n style: TextStyle(fontStyle: FontStyle.italic),\n ),\n ),\n ],\n rows: List.generate(usersFiltered.length, (index) =>\n DataRow(\n cells: <DataCell>[\n DataCell(Text(usersFiltered[index].name)),\n DataCell(Text(usersFiltered[index].age.toString())),\n DataCell(Text(usersFiltered[index].role)),\n ],\n ),\n ),\n ),\n ],\n );\n }\n}\n\nRun Code Online (Sandbox Code Playgroud)\n旧帖子:
\n我正在寻找一种过滤数据表的方法,您的问题解决了我的问题(我现在会尽力帮助您!)。通过使用PaginatoredDataTable小部件而不是 DataTable,我可以实现您想要的结果。这个想法是在将列表传递给源属性之前对其进行过滤。这是我用来过滤列表的代码的一部分。在开关块内,我对其进行过滤以删除其他元素:
\nswitch(filter){\n case "Id d\'exp\xc3\xa9dition":\n expeditionsList = expeditionsList.where((e) => e.expeditionId.toLowerCase() == stringToSearch.toLowerCase()).toList();\n break;\n }\n\nreturn PaginatedDataTable(\n showCheckboxColumn: false,\n rowsPerPage: 5,\n source: DataTableSourceExpedition(\n expeditions: expeditionsList,\n onRowClicked: (index) async {\n await ExpeditionRowDialog.buildExpeditionRowDialog(\n context, expeditionsList[index].expeditionsDetails)\n .show();\n },\n header: Container(\n width: 100,\n child: Text("Exp\xc3\xa9ditions"),\n ),\n columns: [\n DataColumn(\n label: Text("Id d\'exp\xc3\xa9dition"), numeric: false, tooltip: "id"),\n \n ],\n );\nRun Code Online (Sandbox Code Playgroud)\n然后我需要使用需要DataTableSource对象的 source 属性将数据传递到表。我创建了一个扩展DataTableSource的单独类。我将过滤后的列表作为此类的参数传递,并重写 DataTableSource 类的方法:
\nclass DataTableSourceExpedition extends DataTableSource {\n List<Expedition> expeditions = List();\n Function onRowClicked;\n Function onDeleteIconClick;\n final df = DateFormat(\'dd.MM.yyyy\');\n\n DataTableSourceExpedition({this.expeditions, this.onRowClicked, \n this.onDeleteIconClick});\n DataRow getRow(int index) {\n final _expedition = expeditions[index];\n\nreturn DataRow.byIndex(\n index: index,\n cells: <DataCell>[\n DataCell(Text("${_expedition.expeditionId}")),\n DataCell(IconButton(\n icon: Icon(Icons.delete_forever, color: kReturnColor,),\n onPressed: (){onDeleteIconClick(index);},\n ))\n ],\n onSelectChanged: (b) => onRowClicked(index));\n }\n\n\n bool get isRowCountApproximate => false;\n\n\n int get rowCount => expeditions.length;\n\n\n int get selectedRowCount => 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n像这样,我可以过滤唯一的项目,而无需添加空行,如下图所示:
\n\n如果列表为空,它也有效。
\n| 归档时间: |
|
| 查看次数: |
11025 次 |
| 最近记录: |