Flutter 颤振:在列表中搜索
在学习颤振框架/Dart的过程中,我创建了一个示例项目 我有一个名为Flutter 颤振:在列表中搜索,flutter,dart,Flutter,Dart,在学习颤振框架/Dart的过程中,我创建了一个示例项目 我有一个名为person.dart的类,包含以下内容: class Person { String personFirstName; String personLastName; Person( {this.personFirstName, this.personLastName} ); } 接下来,我有一个“builder”类,person\u builder.dart,我在其中创建了人物的示例数据: 导入“p
person.dart
的类,包含以下内容:
class Person {
String personFirstName;
String personLastName;
Person(
{this.personFirstName, this.personLastName}
);
}
接下来,我有一个“builder”类,person\u builder.dart
,我在其中创建了人物的示例数据:
导入“package:adv_search/model/person.dart”
class PersonDataBuilder {
List getPeople() {
return [
Person(
personFirstName: "John",
personLastName: "Smith"
),
Person(
personFirstName: "Alex",
personLastName: "Johnson"
),
Person(
personFirstName: "Jane",
personLastName: "Doe"
),
Person(
personFirstName: "Eric",
personLastName: "Johnson"
),
Person(
personFirstName: "Michael",
personLastName: "Eastwood"
),
Person(
personFirstName: "Benjamin",
personLastName: "Woods"
),
Person(
personFirstName: "Abraham",
personLastName: "Atwood"
),
Person(
personFirstName: "Anna",
personLastName: "Clack"
),
Person(
personFirstName: "Clark",
personLastName: "Phonye"
),
Person(
personFirstName: "Kerry",
personLastName: "Mirk"
),
Person(
personFirstName: "Eliza",
personLastName: "Wu"
),
Person(
personFirstName: "Jackey",
personLastName: "Lee"
),
Person(
personFirstName: "Kristin",
personLastName: "Munson"
),
Person(
personFirstName: "Oliver",
personLastName: "Watson"
),
];
}
}
我已经将搜索功能添加到顶部的导航栏中,很好。。。单击搜索图标后,搜索字段打开(在顶部导航内),允许我提供搜索输入。我有一个具有侦听器的控制器,可以很好地捕获用户输入,如我的main.dart
文件所示:
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:adv_search/model/person.dart';
import 'package:adv_search/data/person_builder.dart';
void main() => runApp(new AdvancedSearch());
class AdvancedSearch extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'List of People',
home: new ListPersonPage(title: 'List of People'),
);
}
}
class ListPersonPage extends StatefulWidget {
ListPersonPage({Key key, this.title}) : super(key: key);
final String title;
@override
_ListPersonPageState createState() => _ListPersonPageState();
}
class _ListPersonPageState extends State<ListPersonPage> {
List people;
TextEditingController controller = new TextEditingController();
String filter;
Widget appBarTitle = new Text("List of People");
Icon actionIcon = new Icon(Icons.search);
@override
void initState() {
PersonDataBuilder pdb = new PersonDataBuilder();
people = pdb.getPeople();
controller.addListener(() {
setState(() {
filter = controller.text;
});
});
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final appTopAppBar = AppBar(
elevation: 0.1,
title: appBarTitle,
actions: <Widget>[
new IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close);
this.appBarTitle = new TextField(
style: new TextStyle(
color: Colors.white,
),
decoration: new InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "Search...",
hintStyle: new TextStyle(color: Colors.white)),
controller: controller,
);
} else {
this.actionIcon = new Icon(Icons.search);
this.appBarTitle = new Text("List of People");
}
});
},
),
],
);
ListTile personListTile(Person person) => ListTile(
title: Text(
person.personFirstName + " " + person.personLastName,
style: TextStyle(color: Colors.black45, fontWeight: FontWeight.bold),
),);
Card personCard(Person person) => Card(
child: Container(
decoration: BoxDecoration(color: Colors.grey[300]),
child: personListTile(person),
),
);
final appBody = Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: people.length,
itemBuilder: (BuildContext context, int index) {
//return filter == null || filter == "" ? personCard(people[index]) : people[index].contains(filter) ? personCard(people[index]) : new Container();
return filter == null || filter == "" ? personCard(people[index]) : new Container();
},
),
);
return Scaffold(
appBar: appTopAppBar,
body: appBody,
);
}
}
我得到的错误是:
NoSuchMethodError:类“Person”没有实例方法“contains”
接收者:“Person”的实例
尝试呼叫:包含(“John”)
鉴于上述错误,目前我根本无法过滤。我想知道:
添加了全部代码文件;对文章的部分内容进行了重新措辞,并添加了几个附加问题。错误正是告诉您代码的错误所在。编写
items[index].contains(searchFilter)
时,编译器会尝试在Person类中查找“contains”方法。由于您还没有实现它,它会抛出一个异常
实现搜索的一种方法如下所示:
List<Person> _personList = [] ;
List<Person> _searchList = [] ;
// populate _personList
_personList.forEach((p) {
if (p.personFirstName == searchFilter or p.personLastName == searchFilter) {
_searchList.add(f);
}
}
Widget _listContents(List<Person> list) {
// implement list view
}
然后定义_listContents如下:
List<Person> _personList = [] ;
List<Person> _searchList = [] ;
// populate _personList
_personList.forEach((p) {
if (p.personFirstName == searchFilter or p.personLastName == searchFilter) {
_searchList.add(f);
}
}
Widget _listContents(List<Person> list) {
// implement list view
}
最后,set_是基于用户交互的搜索 所以这不是小事。。。很可能是因为我不熟悉飞镖/颤振框架。。。无论如何,这个答案建立在@Sukhi回答的基础上: 首先,person\u buider.dart中的
getPeople
方法需要返回类型为List
最后,在main.dart
文件中,发生了以下更改:
\u ListPersonPageState
State
中,我们需要定义两个不同的列表(如@Sukhi所述):List\u personList=[]
和List\u filteredList=[]
initState
方法中:
a。我们需要创建一个临时列表,迭代从PeopleDataBuilder类的getPeople
方法检索的列表,并将返回列表中的每个项添加到我们创建的临时列表中
b。然后,我们设置状态,在它里面,我们将这个临时列表分配给\u personList
,然后将这个\u personList
分配给\u filteredList
c。当我们向控制器添加一个侦听器时,我们会进行一些(健全性)验证,并在此基础上,我们setState
build
方法中,我们需要(再次)创建一个临时列表(如果过滤器不为空),然后将该临时列表分配给\u filteredList
文本字段添加/定义了基本属性(例如光标颜色:Colors.white、
等)
main.dart
code,供参考:
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:adv_search/model/person.dart';
import 'package:adv_search/data/person_builder.dart';
void main() => runApp(new AdvancedSearch());
class AdvancedSearch extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'List of People',
home: new ListPersonPage(title: 'List of People'),
);
}
}
class ListPersonPage extends StatefulWidget {
ListPersonPage({Key key, this.title}) : super(key: key);
final String title;
@override
_ListPersonPageState createState() => _ListPersonPageState();
}
class _ListPersonPageState extends State<ListPersonPage> {
List<Person> _personList = [];
List<Person> _filteredList = [];
TextEditingController controller = new TextEditingController();
String filter = "";
Widget appBarTitle = new Text("List of People");
Icon actionIcon = new Icon(Icons.search);
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
void initState() {
PersonDataBuilder pdb = new PersonDataBuilder();
List<Person> tmpList = new List<Person>();
for(int i=0; i < pdb.getPeople().length; i++) {
tmpList.add(pdb.getPeople()[i]);
}
setState(() {
_personList = tmpList;
_filteredList = _personList;
});
controller.addListener(() {
if(controller.text.isEmpty) {
setState(() {
filter = "";
_filteredList = _personList;
});
} else {
setState(() {
filter = controller.text;
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
final appTopAppBar = AppBar(
elevation: 0.1,
title: appBarTitle,
actions: <Widget>[
new IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close);
this.appBarTitle = new TextField(
controller: controller,
decoration: new InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "Search...",
hintStyle: new TextStyle(color: Colors.white),
),
style: new TextStyle(
color: Colors.white,
),
autofocus: true,
cursorColor: Colors.white,
);
} else {
this.actionIcon = new Icon(Icons.search);
this.appBarTitle = new Text("List of People");
_filteredList = _personList;
controller.clear();
}
});
},
),
],
);
ListTile personListTile(Person person) => ListTile(
title: Text(
person.personFirstName + " " + person.personLastName,
style: TextStyle(color: Colors.black45, fontWeight: FontWeight.bold),
),);
Card personCard(Person person) => Card(
child: Container(
decoration: BoxDecoration(color: Colors.grey[300]),
child: personListTile(person),
),
);
if((filter.isNotEmpty)) {
List<Person> tmpList = new List<Person>();
for(int i = 0; i < _filteredList.length; i++) {
if(_filteredList[i].personFirstName.toLowerCase().contains(filter.toLowerCase())) {
tmpList.add(_filteredList[i]);
}
}
_filteredList = tmpList;
}
final appBody = Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _personList == null ? 0 : _filteredList.length,
itemBuilder: (BuildContext context, int index) {
return personCard(_filteredList[index]);
},
),
);
return Scaffold(
appBar: appTopAppBar,
body: appBody,
);
}
}
导入“包装:颤振/材料.省道”;
进口“包装:颤振/基础.dart”;
导入“package:adv_search/model/person.dart”;
导入“package:adv_search/data/person_builder.dart”;
void main()=>runApp(新的AdvancedSearch());
类AdvancedSearch扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回新材料PP(
标题:“人员名单”,
主页:新建ListPersonPage(标题:“人员列表”),
);
}
}
类ListPersonPage扩展StatefulWidget{
ListPersonPage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_ListPersonPageState createState()=>\u ListPersonPageState();
}
类_ListPersonPageState扩展状态{
列表_personList=[];
列表_filteredList=[];
TextEditingController=新的TextEditingController();
字符串过滤器=”;
Widget appBarTitle=新文本(“人员列表”);
图标操作图标=新图标(Icons.search);
@凌驾
无效处置(){
controller.dispose();
super.dispose();
}
@凌驾
void initState(){
PersonDataBuilder pdb=新的PersonDataBuilder();
List tmpList=新列表();
for(int i=0;iimport 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:adv_search/model/person.dart';
import 'package:adv_search/data/person_builder.dart';
void main() => runApp(new AdvancedSearch());
class AdvancedSearch extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'List of People',
home: new ListPersonPage(title: 'List of People'),
);
}
}
class ListPersonPage extends StatefulWidget {
ListPersonPage({Key key, this.title}) : super(key: key);
final String title;
@override
_ListPersonPageState createState() => _ListPersonPageState();
}
class _ListPersonPageState extends State<ListPersonPage> {
List<Person> _personList = [];
List<Person> _filteredList = [];
TextEditingController controller = new TextEditingController();
String filter = "";
Widget appBarTitle = new Text("List of People");
Icon actionIcon = new Icon(Icons.search);
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
void initState() {
PersonDataBuilder pdb = new PersonDataBuilder();
List<Person> tmpList = new List<Person>();
for(int i=0; i < pdb.getPeople().length; i++) {
tmpList.add(pdb.getPeople()[i]);
}
setState(() {
_personList = tmpList;
_filteredList = _personList;
});
controller.addListener(() {
if(controller.text.isEmpty) {
setState(() {
filter = "";
_filteredList = _personList;
});
} else {
setState(() {
filter = controller.text;
});
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
final appTopAppBar = AppBar(
elevation: 0.1,
title: appBarTitle,
actions: <Widget>[
new IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close);
this.appBarTitle = new TextField(
controller: controller,
decoration: new InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "Search...",
hintStyle: new TextStyle(color: Colors.white),
),
style: new TextStyle(
color: Colors.white,
),
autofocus: true,
cursorColor: Colors.white,
);
} else {
this.actionIcon = new Icon(Icons.search);
this.appBarTitle = new Text("List of People");
_filteredList = _personList;
controller.clear();
}
});
},
),
],
);
ListTile personListTile(Person person) => ListTile(
title: Text(
person.personFirstName + " " + person.personLastName,
style: TextStyle(color: Colors.black45, fontWeight: FontWeight.bold),
),);
Card personCard(Person person) => Card(
child: Container(
decoration: BoxDecoration(color: Colors.grey[300]),
child: personListTile(person),
),
);
if((filter.isNotEmpty)) {
List<Person> tmpList = new List<Person>();
for(int i = 0; i < _filteredList.length; i++) {
if(_filteredList[i].personFirstName.toLowerCase().contains(filter.toLowerCase())) {
tmpList.add(_filteredList[i]);
}
}
_filteredList = tmpList;
}
final appBody = Container(
child: ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: _personList == null ? 0 : _filteredList.length,
itemBuilder: (BuildContext context, int index) {
return personCard(_filteredList[index]);
},
),
);
return Scaffold(
appBar: appTopAppBar,
body: appBody,
);
}
}