本文介绍了Flutter:如何实现工具栏搜索视图以显示2状态之间的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有这样的JSON( API ):
I have JSON like this (API):
[
{
"country": "United States",
"continent": "North America",
"code": "us"
},
{
"country": "Mexico",
"continent": "North America",
"code": "mx"
},
{
"country": "Canada",
"continent": "North America",
"code": "ca"
},
{
"country": "Guatemala",
"continent": "North America",
"code": "gt"
},
{
"country": "Cuba",
"continent": "North America",
"code": "cu"
},
{
"country": "Haiti",
"continent": "North America",
"code": "ht"
},
{
"country": "Russia",
"continent": "Europe",
"code": "ru"
},
{
"country": "Ukraine",
"continent": "Europe",
"code": "ua"
},
{
"country": "France",
"continent": "Europe",
"code": "fr"
},
{
"country": "Spain",
"continent": "Europe",
"code": "es"
},
{
"country": "Sweden",
"continent": "Europe",
"code": "se"
},
{
"country": "Norway",
"continent": "Europe",
"code": "no"
}
]
我想这样实现工具栏搜索视图:
I want to implement Toolbar Search View like this:
我找到了一些基本的教程并进行了尝试,但是,对于像我这样的新手来说,在保持Gridview格式的同时合并两种状态非常困难.所以请帮助我,这是主文件
I have found some basic tutorials and tried it out, however, to combine 2 states while keeping Gridview form is too difficult for a newbie like me. So please help me, this is the main file
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:load_data/search_model.dart';
class SearchPage extends StatefulWidget {
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
List<String> _tabs = ['North America', 'Europe'];
TextEditingController _searchQueryController = TextEditingController();
bool _isSearching = false;
String searchQuery = "Search query";
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: _tabs.length,
child: Scaffold(
appBar: AppBar(
title: Text('List Country'),
bottom: TabBar(
tabs: _tabs.map((String name) => Tab(child: Text(name))).toList(),
),
),
body: FutureBuilder(
future: SearchServices.getData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
List<Widget> children;
List<Search> _search = snapshot.data;
if (snapshot.hasData) {
return TabBarView(
children: _tabs.map((String name) {
return ShowList(search: List<Search>.from(_search)..retainWhere((e) => e.continent == name));
}).toList(),
);
} else {
children = <Widget>[SizedBox(child: CircularProgressIndicator(), width: 60, height: 60), const Padding(padding: EdgeInsets.only(top: 16), child: Text('Loading...'))];
}
return Center(child: Column(mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: children));
}),
),
);
}
}
class ShowList extends StatelessWidget {
final List<Search> search;
const ShowList({Key key, this.search}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemCount: search.length,
itemBuilder: (BuildContext context, int index) {
Search s = search[index];
return Card(
child: Column(children: [
Text(s.country),
Image.network('https://www.countryflags.io/${s.code}/flat/64.png'),
]),
);
},
);
}
}
class SearchServices {
static const String url = 'https://firebasestorage.googleapis.com/v0/b/tft-test-48c87.appspot.com/o/search.json?alt=media&token=08236daf-cc72-4c3b-b052-7822f8790b12';
static Future<List<Search>> getData() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
final List<Search> data = searchFromJson(response.body);
return data;
} else {
return List<Search>();
}
} catch (e) {
return List<Search>();
}
}
}
............................................... ................
...............................................................
推荐答案
您可以在
下复制粘贴运行完整代码您可以在ShowList
You can copy paste run full code below
You can filter searchQuery
in ShowList
代码段
TextField(
decoration: InputDecoration(
hintText: "Country Search",
suffixIcon: Icon(Icons.search),
),
controller: _searchQueryController,
onChanged: (value) {
searchQuery = value;
setState(() {});
},
)
...
const ShowList({Key key, this.search}) : super(key: key);
@override
Widget build(BuildContext context) {
var detail = search
.where(
(s) => s.country.toLowerCase().contains(searchQuery.toLowerCase()))
.toList();
return GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemCount: detail.length,
itemBuilder: (BuildContext context, int index) {
Search s = detail[index];
工作演示
完整代码
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
List<Search> searchFromJson(String str) =>
List<Search>.from(json.decode(str).map((x) => Search.fromJson(x)));
String searchToJson(List<Search> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Search {
Search({
this.country,
this.continent,
this.code,
});
String country;
String continent;
String code;
factory Search.fromJson(Map<String, dynamic> json) => Search(
country: json["country"],
continent: json["continent"],
code: json["code"],
);
Map<String, dynamic> toJson() => {
"country": country,
"continent": continentValues.reverse[continent],
"code": code,
};
}
enum Continent { NORTH_AMERICA, EUROPE }
final continentValues = EnumValues(
{"Europe": Continent.EUROPE, "North America": Continent.NORTH_AMERICA});
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
class SearchPage extends StatefulWidget {
@override
_SearchPageState createState() => _SearchPageState();
}
String searchQuery = "";
class _SearchPageState extends State<SearchPage> {
List<String> _tabs = ['North America', 'Europe'];
TextEditingController _searchQueryController = TextEditingController();
bool _isSearching = false;
Future<List<Search>> _future;
@override
void initState() {
_future = SearchServices.getData();
super.initState();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: _tabs.length,
child: Scaffold(
appBar: AppBar(
title: TextField(
decoration: InputDecoration(
hintText: "Country Search",
suffixIcon: Icon(Icons.search),
),
controller: _searchQueryController,
onChanged: (value) {
searchQuery = value;
setState(() {});
},
),
bottom: TabBar(
tabs: _tabs.map((String name) => Tab(child: Text(name))).toList(),
),
),
body: FutureBuilder(
future: _future,
builder: (BuildContext context, AsyncSnapshot snapshot) {
List<Widget> children;
List<Search> _search = snapshot.data;
if (snapshot.hasData) {
return TabBarView(
children: _tabs.map((String name) {
return ShowList(
search: List<Search>.from(_search)
..retainWhere((e) => e.continent == name));
}).toList(),
);
} else {
children = <Widget>[
SizedBox(
child: CircularProgressIndicator(),
width: 60,
height: 60),
const Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Loading...'))
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children));
}),
),
);
}
}
class ShowList extends StatelessWidget {
final List<Search> search;
const ShowList({Key key, this.search}) : super(key: key);
@override
Widget build(BuildContext context) {
var detail = search
.where(
(s) => s.country.toLowerCase().contains(searchQuery.toLowerCase()))
.toList();
return GridView.builder(
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
itemCount: detail.length,
itemBuilder: (BuildContext context, int index) {
Search s = detail[index];
return Card(
child: Column(children: [
Text(s.country),
Image.network('https://www.countryflags.io/${s.code}/flat/64.png'),
]),
);
},
);
}
}
class SearchServices {
static const String url =
'https://firebasestorage.googleapis.com/v0/b/tft-test-48c87.appspot.com/o/search.json?alt=media&token=08236daf-cc72-4c3b-b052-7822f8790b12';
static Future<List<Search>> getData() async {
try {
final response = await http.get(url);
if (200 == response.statusCode) {
final List<Search> data = searchFromJson(response.body);
return data;
} else {
return List<Search>();
}
} catch (e) {
return List<Search>();
}
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SearchPage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
这篇关于Flutter:如何实现工具栏搜索视图以显示2状态之间的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!