在我的 flutter web 项目中,我有一个对话框,用户可以在其中选择一个项目并另外在文本字段中输入文本。 确认该对话框后,我可以简单地使用 TextController.text 访问文本字段的值。
用户选择的项目来自筹码列表。
在对话框中我设置了这个列表:
OrganizationList(
queryUser: this.widget.queryUser,
style: "chip",
),
这是我的 OrganizationList 类:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:myappname/models/user.dart';
import 'package:myappname/services/database.dart';
import 'package:responsive_builder/responsive_builder.dart';
import 'organization_list_mobile.dart';
import 'organization_list_tablet.dart';
class OrganizationList extends StatelessWidget {
final String style;
final QueryDocumentSnapshot affiliate;
final User queryUser;
OrganizationList({
this.style,
this.affiliate,
this.queryUser,
});
Stream<QuerySnapshot> _organizationsStream;
@override
Widget build(BuildContext context) {
if (this.queryUser == null) {
// all organizations
print("all organizations");
_organizationsStream =
DatabaseService().organizationsCollection.snapshots();
} else {
// user's organizations
print("user's organizations");
_organizationsStream =
DatabaseService(uid: this.queryUser.uid).getUserOrganizations();
}
return StreamBuilder(
stream: _organizationsStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Error: ${snapshot.error}");
}
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
default:
List<QueryDocumentSnapshot> snapshotOrganizations =
snapshot.data.docs;
return ScreenTypeLayout(
mobile: OrientationLayoutBuilder(
landscape: (context) => OrganizationListMobile(
organizations: snapshotOrganizations,
listTileStyle: this.style,
affiliate: this.affiliate,
),
portrait: (context) => OrganizationListMobile(
organizations: snapshotOrganizations,
listTileStyle: this.style,
affiliate: this.affiliate,
),
),
tablet: OrientationLayoutBuilder(
portrait: (context) => OrganizationListTabletPortrait(),
landscape: (context) => OrganizationListMobile(),
),
);
}
});
}
}
目前我正在开发移动视图,所以这里是类 OrganizationListMobile:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:myappname/services/database.dart';
import 'package:myappname/widgets/organization_popup_menu_button/organization_popup_menu_button.dart';
class OrganizationListMobile extends StatefulWidget {
final List<QueryDocumentSnapshot> organizations;
final String listTileStyle;
final QueryDocumentSnapshot affiliate;
const OrganizationListMobile({
Key key,
this.organizations,
this.listTileStyle,
this.affiliate,
});
@override
_OrganizationListMobileState createState() => _OrganizationListMobileState();
}
class _OrganizationListMobileState extends State<OrganizationListMobile> {
final organizationIds = [];
@override
void initState() {
this.widget.organizations.forEach((element) {
organizationIds.add(element.id);
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
height: 200,
child: ListView(
shrinkWrap: true,
children: widget.organizations
.map((organization) => CustomListTile(
userId: this.widget.affiliate != null
? this.widget.affiliate.id
: null,
organization: organization,
style: this.widget.listTileStyle,
organizationIds: this.organizationIds,
))
.toList(),
),
);
}
}
class CustomListTile extends StatefulWidget {
final userId;
final organization;
final style;
final organizationIds;
const CustomListTile(
{Key key,
this.userId,
this.organization,
this.style,
this.organizationIds})
: super(key: key);
@override
_CustomListTileState createState() => _CustomListTileState();
}
class _CustomListTileState extends State<CustomListTile> {
bool isLoading;
bool isSelected;
bool isActivated;
List selectedOrganizationIds;
void onCheckboxChanged(BuildContext context, bool value) {
value
? DatabaseService(uid: this.widget.userId)
.setUserOrganization(context, this.widget.organization.documentID)
: DatabaseService(uid: this.widget.userId).removeUserOrganization(
context, this.widget.organization.documentID);
setState(() {
isSelected = value;
});
}
void onChipChanged(BuildContext context, bool value) {
setState(() {
isSelected = value;
print("onChipSelected" + value.toString());
});
}
@override
void initState() {
switch (this.widget.style) {
case "checkbox":
isLoading = true;
isSelected = false;
_handleSelectionState(this.widget.organization.id, this.widget.userId);
break;
case "chip":
isSelected = false;
break;
}
super.initState();
}
@override
Widget build(BuildContext context) {
print(this.widget.organizationIds);
switch (this.widget.style) {
case "checkbox":
return CheckboxListTile(
title: Text((this.widget.organization.data()['name'] != null)
? this.widget.organization.data()['name']
: ""),
value: isSelected,
onChanged: (!isLoading)
? (bool value) {
onCheckboxChanged(context, value);
}
: null,
);
break;
case "popup":
return ListTile(
title: Text((this.widget.organization.data()['name'] != null)
? this.widget.organization.data()['name']
: ""),
trailing: OrganizationPopupMenuButton(
organization: this.widget.organization,
),
);
break;
default:
/*return RadioListTile(
title: Text((this.widget.organization.data()['name'] != null)
? this.widget.organization.data()['name']
: ""),
value: this.widget.organization.id,
groupValue: this.widget.organizationIds,
/*onChanged: (val) => setState(() => selectedRadioItem = val),
);*/
onChanged: (val) => print("selected ${val}"));
*/
return ChoiceChip(
label: Text((this.widget.organization.data()['name'] != null)
? this.widget.organization.data()['name']
: ""),
avatar: isSelected ? Icon(Icons.check) : null,
selected: isSelected,
onSelected: (bool value) {
onChipChanged(context, value);
},
);
break;
}
}
_handleSelectionState(organizationId, userId) async {
await DatabaseService(uid: userId)
.checkAffiliatedOrganization(organizationId)
.then((result) => setState(() {
isSelected = result;
isLoading = false;
}));
}
}
在提交对话时了解所选组织的最佳方式是什么?有没有办法简单地将值传回给父母?
也许整个设计可能会导致错误的方向。对此有何建议? 一般来说,我担心我在所有这些类之间传递了太多参数。也许有一个完全不同的解决方案我还没有使用过?
如果你们中的一位专业人士可以看看这个,我将不胜感激。
干杯!