Flutter 值为null时显示另一个小部件
我正在我的Flitter应用程序中创建搜索功能。除了一个小问题,我几乎什么都做得很好 这是我到目前为止得到的代码:Flutter 值为null时显示另一个小部件,flutter,Flutter,我正在我的Flitter应用程序中创建搜索功能。除了一个小问题,我几乎什么都做得很好 这是我到目前为止得到的代码: Future<SearchResult> results; Future<SearchResult> getResults(String query) async { var response = await http.get(url + query); if (response.statusCode == 200) { var
Future<SearchResult> results;
Future<SearchResult> getResults(String query) async {
var response = await http.get(url + query);
if (response.statusCode == 200) {
var jsona = json.decode(response.body);
return SearchResult.fromJson(jsona);
} else
throw Exception("Failed to fetch songs");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Container(
height: 55,
decoration: BoxDecoration(
color: Colors.grey, borderRadius: BorderRadius.circular(10)),
child: Row(
children: [
Expanded(
child: Padding(
padding:
const EdgeInsets.only(bottom: 1, left: 10, right: 10),
child: Form(
key: _formKey,
child: TextFormField(
controller: searchController,
decoration: InputDecoration(
border: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
errorBorder: InputBorder.none,
disabledBorder: InputBorder.none,
hintText: "Search for artists"),
validator: (input) {
if (input.isEmpty) {
return "Please enter an artist name";
}
return null;
},
),
),
),
),
SizedBox(width: 20),
Padding(
padding: const EdgeInsets.all(10),
child: GestureDetector(
onTap: () async {
if(_formKey.currentState.validate()){
results = getResults(searchController.text);
}
},
child: Icon(Icons.search),
),
)
],
))),
body: SingleChildScrollView(
child: SafeArea(
child: Column(
children: [
searchResults()
],
),
),
),
);
}
Widget searchResults(){
return StreamBuilder(
stream: results.asStream(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
print("stuck");
return Center(child: Text("No data to display.."));
} else if(snapshot.connectionState == ConnectionState.done){
return ListView.builder(
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.results.length,
itemBuilder: (context, index) {
return ListTile(
title:
Text(snapshot.data.results[index].trackName),
subtitle:
Text(snapshot.data.results[index].artistName),
leading: Image.network(
snapshot.data.results[index].artworkUrl30),
);
});
} else {
return Center(child: Text("Fetching the data..."));
}
});
}
未来结果;
未来getResults(字符串查询)异步{
var response=wait http.get(url+查询);
如果(response.statusCode==200){
var jsona=json.decode(response.body);
返回SearchResult.fromJson(jsona);
}否则
抛出异常(“未能获取歌曲”);
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:集装箱(
身高:55,
装饰:盒子装饰(
颜色:颜色。灰色,边界半径:边界半径。圆形(10)),
孩子:排(
儿童:[
扩大(
孩子:填充(
衬垫:
仅限常量边集(底部:1,左侧:10,右侧:10),
孩子:表格(
键:_formKey,
子项:TextFormField(
控制器:搜索控制器,
装饰:输入装饰(
边框:InputBorder.none,
FocusedOrder:InputBorder.none,
enabledBorder:InputBorder.none,
errorBorder:InputBorder.none,
disabledBorder:InputBorder.none,
hintText:“搜索艺术家”),
验证器:(输入){
if(input.isEmpty){
返回“请输入艺术家姓名”;
}
返回null;
},
),
),
),
),
尺寸箱(宽度:20),
填充物(
填充:常量边集。全部(10),
儿童:手势检测器(
onTap:()异步{
if(_formKey.currentState.validate()){
results=getResults(searchController.text);
}
},
子:图标(Icons.search),
),
)
],
))),
正文:SingleChildScrollView(
儿童:安全区(
子:列(
儿童:[
搜索结果()
],
),
),
),
);
}
小部件搜索结果(){
返回流生成器(
流:results.asStream(),
生成器:(上下文,快照){
如果(!snapshot.hasData){
打印(“卡住”);
返回中心(子项:文本(“无需显示的数据”);
}else if(snapshot.connectionState==connectionState.done){
返回ListView.builder(
物理学:NeverscrollableScroll物理学(),
收缩膜:对,
itemCount:snapshot.data.results.length,
itemBuilder:(上下文,索引){
返回列表块(
标题:
文本(snapshot.data.results[index].trackName),
字幕:
文本(snapshot.data.results[index].artistName),
领先:Image.net(
snapshot.data.results[index].artworkUrl30),
);
});
}否则{
返回中心(子项:文本(“获取数据…”);
}
});
}
这样做的方式是,用户输入一个艺术家的名字,一旦输入完毕,我运行一个函数,在这个函数中我进行一个api调用,以获取该艺术家创作的歌曲。结果存储在结果对象中
基本上,我希望在results对象为null时显示一个文本小部件,然后在加载数据后显示api调用获取的实际结果。我已经处理了数据获取后的显示结果。问题是,在用户搜索艺术家之前,结果为空
当结果为空时,如何显示某些小部件?您有多种方法解决此问题
- 您可以为未来指定一个永远不会完成的默认值:
(另外,您可能可以直接使用而不是带有
Future.asStream
的StreamBuilder)您可以使用FutureBuilder而不是StreamBuilder
Future<SearchResult> results = Future.delayed(Duration(days: 99));
Widget searchResults(){
if (results==null)
return Text('No search made yet.');
else
return StreamBuilder(
[...]
);
}