如何解决Flutter 将内容包含到页面中
当我选择一个结果时,displaySnack() 正在工作,它显示一个snackBar,但我想显示testList() 的内容。
我的目标是了解如何启动另一个小部件,以便能够一次又一次地在页面上添加新的小部件。
我的最终目标是一旦我有了选定的值,就发起一个 http 请求,获取一个列表作为返回值并显示一个列表视图。
(我是新手,所以如果可能的话,请解释你的回答:)) onSuggestionSelected : 是的,我知道它是无效的..
import 'package:drawer/src/share/snack_bar.dart';
import 'package:Flutter/material.dart';
import 'package:Flutter_typeahead/Flutter_typeahead.dart';
import '../models/post_model.dart';
import '../services/http_service.dart';
// import 'package:http/http.dart' as http;
class PostsPage extends StatelessWidget {
final String title;
const PostsPage({Key? key,required this.title}) : super(key: key);
static Future<List<Post>> filterList(String value) async {
List<Post> list = await HttpService.fetchPosts();
return list.where(
(x) => x.title.toLowerCase().contains(value.toLowerCase())).toList();
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(title),),body: SafeArea(
child: Container(
padding: EdgeInsets.all(16),child: TypeAheadField<Post?>(
debounceDuration: Duration(milliseconds: 500),hideSuggestionsOnKeyboardHide: false,textFieldConfiguration: TextFieldConfiguration(
decoration: Inputdecoration(
prefixIcon: Icon(Icons.search),border: OutlineInputBorder(),hintText: 'Select the namespace...',suggestionsCallback: filterList,itemBuilder: (context,Post? suggestion) {
final user = suggestion!;
return ListTile(
title: Text(user.title),);
},noItemsFoundBuilder: (context) => Container(
height: 100,child: Center(
child: Text(
'No Namespace Found.',style: TextStyle(fontSize: 24),onSuggestionSelected: (Post? suggestion) {
final user = suggestion!;
displaySnack(context,' Namespace: '+user.title);
testList(context); ################################ HERE
},);
}
Widget testList(BuildContext context) {
return ListView.separated(
separatorBuilder: (BuildContext context,int index) => const Divider(),itemCount: 2,index) {
return Card(
child: ListTile(
title: Text("ppp"),subtitle: Text("ppp"),leading: CircleAvatar(
backgroundImage: NetworkImage(
"https://images.unsplash.com/photo-1547721064-da6cfb341d50"))
));
});
}
解决方法
很明显,您希望小部件重建以显示结果。最直接的方法是使用StatefulWidget。所以我在你的情况下使用它(你也可以找到很多方法来管理状态List of state management approaches)
- 将您的 PostsPage 更改为 StatefulWidget 并在用户被选中时重新构建
- 在您的 PostsPage 中添加一个 Column 并将其分为 2 部分:TypeAheadField 和 Result
- 结果部分可以使用FutureBuilder(可以在数据未准备好时显示加载指示器)
帖子页面:
class PostsPage extends StatefulWidget {
final String title;
const PostsPage({Key? key,required this.title}) : super(key: key);
static Future<List<Post>> filterList(String value) async {
// skip
}
@override
_PostsPageState createState() => _PostsPageState();
}
class _PostsPageState extends State<PostsPage> {
Post? user;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),),body: SafeArea(
child: Column(
children: [
Container(
padding: EdgeInsets.all(16),child: TypeAheadField<Post>(
// ...
// skip
// ...
onSuggestionSelected: (Post? suggestion) {
setState(() {
user = suggestion!;
displaySnack(context,' Namespace: '+user.title);
});
},Expanded(child: MyResult(post: user)),],);
}
}
结果部分: (我把它做成一个孤立的 StatelessWidget 只是为了更好的阅读。你可以用原来的方法来构建这个小部件)
class MyResult extends StatelessWidget {
const MyResult({
required this.post,Key? key,}) : super(key: key);
final Post? post;
Future<List<OtherObject>> getOtherObjects(Post? post) async{
if(post == null){
return [];
}else{
return Future.delayed(Duration(seconds:3),()=>[OtherObject(title: '001'),OtherObject(title: '002'),OtherObject(title: '003')]);
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<List<OtherObject>>(
future: getOtherObjects(post),builder: (context,snapshot) {
if(snapshot.hasData && snapshot.connectionState == ConnectionState.done) {
final result = snapshot.data!;
return ListView.separated(
separatorBuilder: (BuildContext context,int index) => const Divider(),itemCount: result.length,itemBuilder: (context,index) {
return Card(
child: ListTile(
title: Text(result[index].title),subtitle: Text("ppp"),leading: CircleAvatar(
backgroundImage: NetworkImage(
"https://images.unsplash.com/photo-1547721064-da6cfb341d50"),);
},);
}else {
return Center(child: CircularProgressIndicator());
}
}
);
}
}
,
所以你所做的基本上只是用你的 ListView
函数调用创建一个 testList()
并且什么都不做,但是你想要做的是让那个小部件显示在屏幕上,对吗?
如果您创建一个新的 Widget,Flutter 不仅会显示 Widget,您还必须告诉它进行渲染。想象一下,你正在准备 Widgets(例如 Widgets 中的 Widgets),而 Flutter 会在你没有完成的情况下立即将它渲染到屏幕上,那不会那么好。
您需要将该小部件推送到 Flutter 为您提供的 Navigator
小部件上。
onSuggestionSelected: (Post? suggestion) {
final user = suggestion!;
displaySnack(context,' Namespace: '+user.title);
Navigator.push(
context,MaterialPageRoute(builder: (context) => testList(context)),);
}
我建议您阅读这篇文章Navigation Basics。
,您可以使用 listView 构建器来显示选定的结果。
int
,
如果您想显示所选项目的列表,则必须在小部件树中添加一个 ListView
。还要使用 StatefullWidget
而不是 StatelessWidget
,因为每当您选择一个项目时,所选列表都会因此而改变。
状态示例代码
List<Post> selectedPosts;
@override
void initState() {
super.initState();
selectedPosts = [];
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(title),body: SafeArea(
child: Column(
children: [
Container(
padding: EdgeInsets.all(16),child: TypeAheadField<Post?>(
debounceDuration: Duration(milliseconds: 500),hideSuggestionsOnKeyboardHide: false,textFieldConfiguration: TextFieldConfiguration(
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),border: OutlineInputBorder(),hintText: 'Select the namespace...',suggestionsCallback: filterList,Post? suggestion) {
final user = suggestion!;
return ListTile(
title: Text(user.title),);
},noItemsFoundBuilder: (context) => Container(
height: 100,child: Center(
child: Text(
'No Namespace Found.',style: TextStyle(fontSize: 24),onSuggestionSelected: (Post? suggestion) {
final user = suggestion!;
displaySnack(context,' Namespace: '+user.title);
setState(()=> selectedPosts.add(suggestion));
},testList(context),);
并在 testList
函数中更改 itemcount
itemCount: 2,
到
itemCount: selectedPosts?.length ?? 0,
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。