[英]Flutter - How to implement a Dropdown List using BloC?
我想在我的应用程序中添加一个包含“名称”的下拉列表,而不是像我在下面的代码中那样的 TextField。 我怎样才能使用 BloC 做到这一点?
class PersonPage extends StatefulWidget {
PersonPage(this.person);
final Person person;
@override
_PersonPageState createState() => _PersonPageState();
}
class Names{
const Item(this.name);
final String name;
}
class _PersonPageState extends State<PersonPage> {
Item selectedUser;
List<Item> names = <Names>[
const Item('Thomas'),
const Item('John'),
const Item('Mary'),
const Item('Lukas'),
];
TextEditingController _nameController;
final _bloc = PersonBloc();
@override
void initState() {
_bloc.setPerson(widget.person);
_nameController = TextEditingController(text: widget.person.name);
super.initState();
}
@override
void dispose() {
_nameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("MyApp"),
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: <Widget>[
Container(
child: TextField(
decoration: InputDecoration(labelText: "Name"),
controller: _nameController,
onChanged: _bloc.setName,
),
),
Container(
height: 20,
),
RaisedButton(
child: Text("Save"),
onPressed: () {
if (_bloc.insertOrUpdate()) {
Navigator.pop(context);
}
},
)
],
),
),
),
);
}
谢谢。
我会给你一个例子,你尝试在你的代码中应用
class _PersonPageState extends State<PersonPage> {
final _bloc = PersonBloc();
@override
void initState() {
_bloc.setPerson(widget.person);
_nameController = TextEditingController(text: widget.person.name);
super.initState();
}
@override
void dispose() {
_nameController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("MyApp"),
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListView(
children: <Widget>[
StreamBuilder(
stream: bloc.outName,
builder: (context, snapshot) {
if (!snapshot.hasData)
return Container();
return DropdownButton(
hint: Text("Names"),
value: snapshot.data,
items: bloc.names.map((item) {
return DropdownMenuItem(
value: item,
child: Row(children: <Widget>[Text(item),]),
);
}).toList(),
onChanged: bloc.inName,
);
},
),
Container(
height: 20,
),
RaisedButton(
child: Text("Save"),
onPressed: () {
if (_bloc.insertOrUpdate()) {
Navigator.pop(context);
}
},
)
],
),
),
),
);
}
将您的姓名列表更改为您的 BLoC,并创建名称BehaviorSubject
PersonBloc{
List<String> names = ['Thomas', 'John', 'Mary', 'Lukas'];
final _name = BehaviorSubject<String>.seeded("");
Stream<String> get outName => _name.stream;
Function(String) get inName => _name.sink.add;
//TODO - Don't forget to dispose this _name
}
现在您的_name
具有选定的名称,要获取名称,您只需要执行
Person.name = _name.stream.value;
这个例子可以改进,只是草稿
这是 model 的空安全示例:
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const CountryPage(),
);
}
}
class CountryPage extends StatefulWidget {
const CountryPage({Key? key}) : super(key: key);
@override
State<CountryPage> createState() => _CountryPageState();
}
class _CountryPageState extends State<CountryPage> {
final _bloc = CountryBloc();
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("MyApp"),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
border: Border.all(width: 1.2, color: Colors.grey)),
child: CustomDropDown(bloc: _bloc),
),
),
);
}
}
class CustomDropDown extends StatelessWidget {
const CustomDropDown({
Key? key,
required CountryBloc bloc,
}) : _bloc = bloc,
super(key: key);
final CountryBloc _bloc;
@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: _bloc.streamReference,
builder: (context, snapshot) {
if (!snapshot.hasData) return Container();
return DropdownButton(
isExpanded: true,
hint: Padding(
padding: const EdgeInsets.all(8.0),
child: Text("${_bloc.getCountry.name}"),
),
underline: const SizedBox(),
icon: const Icon(Icons.keyboard_arrow_down, size: 32.0),
items: _bloc.countries.map((item) {
return DropdownMenuItem(
value: item,
child: Directionality(
textDirection: Directionality.of(context).index == 0
? TextDirection.rtl
: TextDirection.ltr,
child: Container(
margin: const EdgeInsets.only(bottom: 4.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
border: Border.all(width: 1.2, color: Colors.grey)),
child: Align(
alignment: AlignmentDirectional.centerStart,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: Text("${item.name}"),
)),
),
),
);
}).toList(),
onChanged: (value) {
_bloc.selectCountry(value as ObjectModel);
},
);
},
);
}
}
class CountryBloc {
List<ObjectModel> countries = [
ObjectModel(id: "0", name: 'USA'),
ObjectModel(id: "1", name: 'CHINA'),
ObjectModel(id: "2", name: 'INDIA'),
ObjectModel(id: "3", name: 'BRAZIL'),
];
final _country = BehaviorSubject<ObjectModel>.seeded(
ObjectModel(id: "-1", name: "Select Country Name.."));
Stream<ObjectModel> get streamReference => _country.stream;
Function(ObjectModel) get selectCountry => _country.sink.add;
ObjectModel get getCountry => _country.value;
void setCountry(ObjectModel country) {
_country.value = country;
}
}
class ObjectModel {
String? id;
String? name;
ObjectModel({this.id, this.name});
ObjectModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
return data;
}
}
将此依赖项添加到 pubspec.yaml 文件:
flutter_bloc: ^7.1.0
rxdart: ^0.27.5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.