Flutter:如何从 FutureBuilder Listview 中搜索
Flutter: How to search from FutureBuilder Listview
我是 Flutter 的新手,正在尝试完成我的应用程序的最后剩余部分。我正在使用 Firebase 实时数据库存储员工数据并使用 ListView.builder 列出它。我能够显示列表中的所有信息,但我想实现搜索栏。我开始并将它放在控制器中并在终端中显示,但不确定如何正确实施它来过滤数据。
我将通过我的完整代码,但删除 firebase 数据库,因为它现在打开进行测试。
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'directory_details_screen.dart';
class Directory extends StatefulWidget {
// const ({Key? key}) : super(key: key);
@override
_DirectoryState createState() => _DirectoryState();
}
class _DirectoryState extends State<Directory> {
TextEditingController _searchController = TextEditingController();
Future getEmpData() async {
var response = await http.get(Uri.parse(
'FIREBASE REMOVED'));
var jsonData = jsonDecode(response.body);
List<Employee> employees = [];
for (var e in jsonData) {
Employee employee = Employee(
e["displayName"],
e["department"],
e["jobTitle"],
e["mobilePhone"],
e["workEmail"],
e["photoUrl"],
e["workPhoneExtension"]);
employees.add(employee);
}
print(employees.length);
return employees;
}
@override
void initState() {
super.initState();
_searchController.addListener(_onSearchChanged);
}
@override
void dispose() {
_searchController.removeListener(_onSearchChanged);
_searchController.dispose();
super.dispose();
}
_onSearchChanged() {
print(_searchController.text);
}
String searchString = "";
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TextField(
onChanged: (value) {
setState(() {
searchString = value;
});
},
controller: _searchController,
decoration: InputDecoration(
labelText: 'Search',
suffixIcon: Icon(Icons.search),
),
),
),
SizedBox(height: 10),
Expanded(
child: FutureBuilder(
future: getEmpData(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, i) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
snapshot.data[i].photoUrl
),
),
//leading: Icon(Icons.account_circle),
isThreeLine: true,
title: Text(snapshot.data[i].displayName,
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text("Department: " +
snapshot.data[i].department +
"\n" +
"Title: " +
snapshot.data[i].jobTitle),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EmployeeDetails(
employee: snapshot.data[i])));
},
),
);
});
},
),
),
],
),
);
}
}
class Employee {
final String displayName,
department,
jobTitle,
mobilePhone,
workEmail,
photoUrl,
workPhoneExtension;
Employee(this.displayName, this.department, this.jobTitle, this.mobilePhone,
this.workEmail, this.photoUrl, this.workPhoneExtension);
}
您可以尝试这样的操作:
...
} else {
final result = _search(snapshot.data);
return ListView.builder(
itemCount: result.length,
itemBuilder: (context, i) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
result[i].photoUrl
),
),
//leading: Icon(Icons.account_circle),
isThreeLine: true,
title: Text(result[i].displayName,
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text("Department: " +
result[i].department +
"\n" +
"Title: " +
result[i].jobTitle),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
EmployeeDetails(
employee: result[i])));
},
),
);
});
...
和类似
的搜索方法
List<Employee> _search(List<Employee>? employee) {
if(searchString?.isNotEmpty == true) {
//search logic what you want
return employee?.where((element) => element.department.contains(searchString))
.toList() ?? <Employee>[];
}
return employee ?? <Employee>[];
}
我是 Flutter 的新手,正在尝试完成我的应用程序的最后剩余部分。我正在使用 Firebase 实时数据库存储员工数据并使用 ListView.builder 列出它。我能够显示列表中的所有信息,但我想实现搜索栏。我开始并将它放在控制器中并在终端中显示,但不确定如何正确实施它来过滤数据。
我将通过我的完整代码,但删除 firebase 数据库,因为它现在打开进行测试。
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'directory_details_screen.dart';
class Directory extends StatefulWidget {
// const ({Key? key}) : super(key: key);
@override
_DirectoryState createState() => _DirectoryState();
}
class _DirectoryState extends State<Directory> {
TextEditingController _searchController = TextEditingController();
Future getEmpData() async {
var response = await http.get(Uri.parse(
'FIREBASE REMOVED'));
var jsonData = jsonDecode(response.body);
List<Employee> employees = [];
for (var e in jsonData) {
Employee employee = Employee(
e["displayName"],
e["department"],
e["jobTitle"],
e["mobilePhone"],
e["workEmail"],
e["photoUrl"],
e["workPhoneExtension"]);
employees.add(employee);
}
print(employees.length);
return employees;
}
@override
void initState() {
super.initState();
_searchController.addListener(_onSearchChanged);
}
@override
void dispose() {
_searchController.removeListener(_onSearchChanged);
_searchController.dispose();
super.dispose();
}
_onSearchChanged() {
print(_searchController.text);
}
String searchString = "";
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 10),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 15.0),
child: TextField(
onChanged: (value) {
setState(() {
searchString = value;
});
},
controller: _searchController,
decoration: InputDecoration(
labelText: 'Search',
suffixIcon: Icon(Icons.search),
),
),
),
SizedBox(height: 10),
Expanded(
child: FutureBuilder(
future: getEmpData(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.data == null) {
return Container(
child: Center(
child: CircularProgressIndicator(),
),
);
} else
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, i) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
snapshot.data[i].photoUrl
),
),
//leading: Icon(Icons.account_circle),
isThreeLine: true,
title: Text(snapshot.data[i].displayName,
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text("Department: " +
snapshot.data[i].department +
"\n" +
"Title: " +
snapshot.data[i].jobTitle),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => EmployeeDetails(
employee: snapshot.data[i])));
},
),
);
});
},
),
),
],
),
);
}
}
class Employee {
final String displayName,
department,
jobTitle,
mobilePhone,
workEmail,
photoUrl,
workPhoneExtension;
Employee(this.displayName, this.department, this.jobTitle, this.mobilePhone,
this.workEmail, this.photoUrl, this.workPhoneExtension);
}
您可以尝试这样的操作:
...
} else {
final result = _search(snapshot.data);
return ListView.builder(
itemCount: result.length,
itemBuilder: (context, i) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(
result[i].photoUrl
),
),
//leading: Icon(Icons.account_circle),
isThreeLine: true,
title: Text(result[i].displayName,
style: TextStyle(fontWeight: FontWeight.bold)),
subtitle: Text("Department: " +
result[i].department +
"\n" +
"Title: " +
result[i].jobTitle),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
EmployeeDetails(
employee: result[i])));
},
),
);
});
...
和类似
的搜索方法List<Employee> _search(List<Employee>? employee) {
if(searchString?.isNotEmpty == true) {
//search logic what you want
return employee?.where((element) => element.department.contains(searchString))
.toList() ?? <Employee>[];
}
return employee ?? <Employee>[];
}