flutter - Flutter - 使用相同的提供程序更新下拉列表并将数据发送到另一个小部件
问题描述
我想将选定的值从 DropDown 传递给它的父级,然后通过构造函数传递给子级,然后通过 setState 函数更新列表。
所以,我希望从下拉列表中选择的值可以在限制(UserOffers)的子项中访问。
将数据从父级发送到子级它实际工作,但只有当我通过构造函数将父类中定义的数据传递给子级时=我不确定它是否是一个好方法。
现在我只使用提供程序来更新 Dropdown 上的数据,但我不知道如何传递它。
CountryProvider 类:
class CountryProvider with ChangeNotifier {
List<String> _items = [
"Argentina",
"Brazil",
...
"Spain",
"Switzerland",
];
String _selectedItem;
List<String> get items => _items;
String get selected => _selectedItem;
void setSelectedItem(String s) {
_selectedItem = s;
notifyListeners();
}
}
CountryDropDown 类:
class CountryDropDown extends StatefulWidget {
@override
_CountryDropDownState createState() => _CountryDropDownState();
}
class _CountryDropDownState extends State<CountryDropDown> {
@override
void initState() {
super.initState();
}
...
ChangeNotifierProvider<CountryProvider>(
create: (context) => CountryProvider(),
child: Container(
width: 215,
child: Consumer<CountryProvider>(
builder: (_, provider, __) {
return DropdownButton<String>(
hint: Text("Not selected"),
icon: Icon(Icons.flight),
value: dropdownValue,
onChanged: (String newValue) {
provider.setSelectedItem(newValue);
dropdownValue = provider.selected;
print(newValue);
},
items: provider.items
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
...
和家长:
限制类:
class Restrictions extends StatefulWidget {
@override
_RestrictionsState createState() => _RestrictionsState();
}
class _RestrictionsState extends State<Restrictions> {
@override
void initState() {
super.initState();
}
...
Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 20),
child: FieldDropDown(),
),
Container(
padding: EdgeInsets.only(top: 10),
margin: EdgeInsets.only(left: 20),
child: CountryDropDown(),
),
],
),
Container(
child: DateSelector(),
),
],
),
Container(
child: UserOffers(
country: selectedCountry,
field: selectedField,
),
...
解决方案
@博拉斯!你为我做了很多工作...
。
我认为您需要将状态提升到小部件树的更高位置,以便UserOffers
当用户从下拉菜单中选择一个国家/地区时可以更改。
完整的示例应用程序如下。
请注意,我将模型类名称更改为SingleSelectCountry
. 该模型类的实例不是提供者。该模型类的一个实例是由提供者提供的。那里有一个重要的区别。
另请注意,所有小部件都扩展了StatelessWidget
. 通常使用包提供程序可以避免使用StatefulWidget
.
import 'dart:collection';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// Model ---------------------------------------------------
class SingleSelectCountry with ChangeNotifier {
final List<String> _items = <String>[
"Argentina",
"Belgium",
"Brazil",
"Denmark",
"England",
"France",
"Finland",
"Germany",
"Holland",
"Ireland",
"Norway",
"Poland",
"Scotland",
"Spain",
"Sweden",
"Switzerland",
"Wales",
];
String _selectedItem;
UnmodifiableListView<String> get items {
return UnmodifiableListView(this._items);
}
String get selected {
return this._selectedItem;
}
set selected(final String item) {
this._selectedItem = item;
this.notifyListeners();
}
}
// User Interface ------------------------------------------
void main() {
return runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(final BuildContext context) {
// The provider has to be in the widget tree higher than
// both `CountryDropDown` and `UserOffers`.
return MultiProvider(
providers: [
ChangeNotifierProvider<SingleSelectCountry>(
create: (final BuildContext context) {
return SingleSelectCountry();
},
),
],
child: Scaffold(
appBar: AppBar(
title: Text('My Home Page'),
),
body: Restrictions(),
),
);
}
}
class Restrictions extends StatelessWidget {
@override
Widget build(final BuildContext context) {
return Column(
children: <Widget>[
CountryDropDown(),
UserOffers(),
],
);
}
}
class CountryDropDown extends StatelessWidget {
@override
Widget build(final BuildContext context) {
return Consumer<SingleSelectCountry>(
builder: (
final BuildContext context,
final SingleSelectCountry singleSelectCountry,
final Widget child,
) {
return DropdownButton<String>(
hint: const Text("Not selected"),
icon: const Icon(Icons.flight),
value: singleSelectCountry.selected,
onChanged: (final String newValue) {
singleSelectCountry.selected = newValue;
},
items: singleSelectCountry.items.map<DropdownMenuItem<String>>(
(final String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
},
).toList(),
);
},
);
}
}
class UserOffers extends StatelessWidget {
@override
Widget build(final BuildContext context) {
return Consumer<SingleSelectCountry>(
builder: (
final BuildContext context,
final SingleSelectCountry singleSelectCountry,
final Widget child,
) {
return Text(singleSelectCountry.selected ?? '');
},
);
}
}
推荐阅读
- highcharts - 将交互式气泡添加到 highcharts
- html - UIPath 数据抓取 - 抓取元素名称
- databricks - 如何从 REST API 设置作业权限?
- shell - 如何使用 shell 脚本仅在文本文件中每行的第一个单词中添加双引号?
- javascript - 如何在选择选项反应js中选择'country_name'
- c# - 在 C# 中上传到 SQL Server 之前重命名文件名?
- c# - 更改 c# 模型上的字典
- elasticsearch - 如何在 ES 过滤器中选择最长的标记
- php - 教义实体扩展功能
- typescript - TypeScript 泛型函数参数和返回类型推断