此代码旨在通过在文本搜索字段中输入的术语来过滤列表视图。但我收到以下错误。请有人指出我正确的方向(我试图将代码合并到 https://learnflutter.co/flutter-listview-builder-search/):
lib/main.dart:82:51:错误:未为类“ItemList”定义方法“_runFilter”。
这是代码:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(Home());
}
class Home extends StatelessWidget {
// const Home({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'APP TITLE',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (context) => ItemList(),
'/factfile': (context) => ItemDetails(),
},
);
}
}
class ItemList extends StatelessWidget {
ItemList({Key? key}) : super(key: key) {
_stream = _reference.snapshots();
}
// Query _reference = FirebaseFirestore.instance.collection('collection_name').orderBy("dlastupd", descending: true);
Query _reference = FirebaseFirestore.instance.collection('table_name').orderBy(
"dlastupd", descending: true);
late Stream<QuerySnapshot> _stream;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Updates'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(18.0),
child:
TextField(
onChanged: (value) => _runFilter(value),
decoration: InputDecoration(
labelText: 'Search', suffixIcon: Icon(Icons.search)),
),
),
const SizedBox(
height: 20,
),
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: _stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
//Check error
if (snapshot.hasError) {
return Center(child: Text('Some error occurred ${snapshot.error}'));
}
//Check if data arrived
if (snapshot.hasData) {
//get the data
QuerySnapshot querySnapshot = snapshot.data;
List<QueryDocumentSnapshot> documents = querySnapshot.docs;
//Convert the documents to Maps
List<Map> items = documents.map((e) =>
{
'name': e['name'],
'country': e['country'],
'dlastupd': e['dlastupd'],
'dlastupd date': DateTime.fromMillisecondsSinceEpoch(
e['dlastupd'] * 1000),
'id': e['id'],
'type': e['type'],
}).toList();
List<Map<dynamic, dynamic>> _foundItems = [];
@override
initState() {
_foundItems = items;
// super.initState();
initState();
}
void _runFilter(String enteredKeyword)
{
List<Map<dynamic, dynamic>> results = [];
if (enteredKeyword.isEmpty) {
// if the search field is empty or only contains white space
results = items;
} else {
results = items
.where((item) =>
item["name"].toLowerCase().contains(enteredKeyword.toLowerCase()))
.toList();
}
}
//Display the list
print(_foundItems.length);
return ListView.builder(
itemCount: _foundItems.length,
itemBuilder: (BuildContext context, int index) {
//Get the item at this index
Map thisItem = items[index];
//Return the widget for the list items
return ListTile(
title:
Text.rich(
TextSpan(
children: [
TextSpan(text: formatDate(thisItem['dlastupd date'], [d, '', M]) + " " + thisItem['country'] + " (" + thisItem['type'][0] + thisItem['type'][1] + ") - " + thisItem['name'] + " " ,
style: TextStyle(fontWeight: FontWeight.normal)),
]
)
),
onTap: () {
Navigator.pushNamed(
context,
'/factfile',
arguments: {
'id': thisItem['id'],
},
);
},
);
}); }
//Show loader
return Center(child: CircularProgressIndicator());
}
)
)
]
)
);
}
}
在您的代码中,_runFilter方法在ItemList类的build方法中定义。
但是,它应该被定义为 ItemList 类本身的方法。
以下是如何重构代码以正确定义 _runFilter 方法:
class ItemList extends StatelessWidget {
ItemList({Key? key}) : super(key: key) {
_stream = _reference.snapshots();
_foundItems = items; // Initialize _foundItems with items
}
final Query _reference = FirebaseFirestore.instance.collection('table_name').orderBy(
"dlastupd", descending: true);
late final Stream<QuerySnapshot> _stream;
late List<Map<dynamic, dynamic>> _foundItems;
final List<Map<dynamic, dynamic>> items = [];
void _runFilter(String enteredKeyword) {
if (enteredKeyword.isEmpty) {
// if the search field is empty or only contains white space
_foundItems = items;
} else {
_foundItems = items
.where((item) =>
item["name"].toLowerCase().contains(enteredKeyword.toLowerCase()))
.toList();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Updates'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(18.0),
child: TextField(
onChanged: (value) => _runFilter(value),
decoration: InputDecoration(
labelText: 'Search', suffixIcon: Icon(Icons.search)),
),
),
const SizedBox(
height: 20,
),
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: _stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Some error occurred ${snapshot.error}'));
}
if (snapshot.hasData) {
QuerySnapshot querySnapshot = snapshot.data;
List<QueryDocumentSnapshot> documents = querySnapshot.docs;
items.clear(); // Clear items to avoid duplication
items.addAll(documents.map((e) =>
{
'name': e['name'],
'country': e['country'],
'dlastupd': e['dlastupd'],
'dlastupd date': DateTime.fromMillisecondsSinceEpoch(
e['dlastupd'] * 1000),
'id': e['id'],
'type': e['type'],
}));
_runFilter(""); // Filter items initially with an empty string
return ListView.builder(
itemCount: _foundItems.length,
itemBuilder: (BuildContext context, int index) {
Map thisItem = _foundItems[index];
return ListTile(
title: Text.rich(
TextSpan(
children: [
TextSpan(text: formatDate(thisItem['dlastupd date'], [d, '', M]) + " " + thisItem['country'] + " (" + thisItem['type'][0] + thisItem['type'][1] + ") - " + thisItem['name'] + " " ,
style: TextStyle(fontWeight: FontWeight.normal)),
]
)
),
onTap: () {
Navigator.pushNamed(
context,
'/factfile',
arguments: {
'id': thisItem['id'],
},
);
},
);
});
}
return Center(child: CircularProgressIndicator());
},
),
),
],
),
);
}
}