flutter - Flutter - 如何在另一个类上显示/隐藏小部件
问题描述
我有 2 节课,第 1 节是Main Widget Screen
,第 2 节是List Card
. 在 View Perspective 中,Main Widget Screen
Class 包含List Widget
来自List Card Widget
Class ,如下图所示:
在List Card
Widget 上,每个列表都有 2 Text:Text1
和Text2
.
此外,还有 2 个按钮:this month
和last month
. data onList Card Widget
将根据Bloc Stream ZikirHistoryBloc.onChangeTab()
刷新。默认为this month
.
我想要实现的是:
如何显示/隐藏(开/关)
Text1
和Text2
按按钮Main Screen
?
到目前为止我的努力:
主屏幕类:
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() {
return new _MainScreenState();
}
}
class _MainScreenState extends State<MainScreen> {
ZikirHistoryBloc zikirHistoryBloc;
int selectedValue = 1;
...
@override
Widget build(BuildContext context) {
return Scaffold(
...
Expanded(
child: ButtonMenuWidget(
image: "assets/images/zikir/button-text1.png",
title: translations.text("button_show_hide_text1"),
subtitle: point,
onTap: () {
//This is action for Button for Show/Hide Text1**
}
)
),
Expanded(
child: ButtonMenuWidget(
image: "assets/images/home/button-text2.png",
title: translations.text("button_show_hide_text2"),
subtitle: dzikir,
onTap: () {
//This is action for Button for Show/Hide Text1**
}
)
),
...
SizedBox(
width: 1000,
child: Padding(
padding: EdgeInsets.all(8),
child: StreamBuilder(
stream: zikirHistoryBloc.tabSelectedValueStream,
builder: (context, snapshot) {
return CupertinoSegmentedControl<int>(
selectedColor: Pigment.fromString(UIData.primaryColor),
borderColor: Pigment.fromString(UIData.primaryColor),
children: <int, Widget>{
0: Text(translations.text("last_month").toString()),
1: Text(translations.text("this_month").toString()),
},
onValueChanged: (int newValue) {
zikirHistoryBloc.onChangeTab(newValue);
},
groupValue: snapshot.data,
);
}
),
)
),
...
this.HistoriesWidget(),
...
}//::end of Widget build
...
Widget HistoriesWidget() {
return StreamBuilder(
stream: zikirHistoryBloc.dzikirHistoriesStream,
builder: (BuildContext ctx, AsyncSnapshot<List<DzikirHistory>> snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
if (!snapshot.hasData) return Center(child: ActivityIndicatorWidget());
if (snapshot.data.length <= 0) return Center(child: Text(translations.text("empty_data")));
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
primary: false,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (ctx, i) {
//**Below will call class ListCardWidget**
return ListCardWidget(dzikirHistory: snapshot.data[i]);
}
);
}
);
}
...
} //::end of Class `Main Screen`
列表卡小部件类:
class ListCardWidget extends StatefulWidget {
DzikirHistory dzikirHistory;
ListCardWidget({this.dzikirHistory});
@override
_ListCardWidget createState() {
return new _ListCardWidget(dzikirHistory: dzikirHistory);
}
}
class _ListCardWidget extends State<ListCardWidget> {
bool isHiddenText1;
bool isHiddenText2;
DzikirHistory dzikirHistory;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
isHiddenText1 ? Container() : this.Text1Row(context),
isHiddenText2 ? Container() : this.Text2Row(context),
SizedBox(height: 10,),
],
)
],
),
),
Divider(height: 2, color: Pigment.fromString(UIData.primaryColor),),
],
);
}
Widget Text1Row(context) {
return Column(
children: <Widget>[
SizedBox(height: 10,),
Row(
children: <Widget>[
SizedBox(child: Image.asset("assets/images/home/my-zikir-total.png"),height: 20, width: 20,),
SizedBox(width: 10,),
Text('Text 1 ='+getNumberFormat(dzikirHistory.dzikirTotal.toString()),
style: TextStyle(
fontSize: 16,
color: Pigment.fromString(UIData.primaryColor)
),
),
],
),
],
);
}
Widget Text2Row(context) {
return Column(
children: <Widget>[
SizedBox(height: 10,),
Row(
children: <Widget>[
SizedBox(child: Image.asset("assets/images/home/my-point.png"),height: 20, width: 20,),
SizedBox(width: 10,),
Text('Text 2 ='+getNumberFormat(dzikirHistory.counter.toString()),
style: TextStyle(
fontSize: 16,
color: Pigment.fromString(UIData.primaryColor)
),
),
],
),
],
);
}
getNumberFormat(String str) {
final f = new NumberFormat("#.###");
return str.replaceAll(f.symbols.GROUP_SEP, '');
}
...
}//end of class List Card Widget
其他类(型号):
class DzikirHistory {
static const CATEGORY_POINT = "point";
static const CATEGORY_DZIKIR = "dzikir";
int id;
int counter;
int dzikirTotal;
String dzikirDate;
dynamic status;
dynamic createdAt;
dynamic updatedAt;
List<DzikirDetail> dzikirDetails;
DzikirHistory({
this.id,
this.counter,
this.dzikirTotal,
this.dzikirDate,
this.status,
this.createdAt,
this.updatedAt,
this.dzikirDetails
});
factory DzikirHistory.fromJson(Map<String, dynamic> json) => new DzikirHistory(
id: json["id"],
counter: json["counter"],
dzikirTotal: json["dzikir_total"],
dzikirDate: json["dzikir_date"],
status: json["status"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
// dzikirDetails: new List<DzikirDetail>.from(json["dzikir_details"].map((x) => DzikirDetail.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"counter": counter,
"dzikir_total": dzikirTotal,
"dzikir_date": dzikirDate,
"status": status,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
// "dzikir_details": new List<dynamic>.from(dzikirDetails.map((x) => x.toJson())),
};
}
集团代码:
class ZikirHistoryBloc extends Object implements BlocBase {
...
init() async {
_tabSelectedValueController.sink.add(1);
_userController.sink.add(User.fromJson(await Storage.getUser()));
}
onChangeTab(int segment) {
_tabSelectedValueController.sink.add(segment);
if (segment == 1) {
_dzikirHistoriesController.sink.add(dzikirHistories);
} else {
_dzikirHistoriesController.sink.add(dzikirLastHistories);
}
}
...
}
任何想法 ?
提前致谢
更新
使用@FadhliS解决方案不起作用,因为当我上个月单击时,数据不会刷新(以前是正常的)。此外,仅当我单击上个月或本月按钮时,显示/隐藏才有效。
解决方案
最好的解决方案是使用继承的 widget/provider/scopedModel 插件,因为您希望在从父级到子级的许多类中全局管理状态。您应该阅读这些并将它们合并到您的项目中。
但你也可以试试这个,这是一个小修复,但不是理想的解决方案
在您的父状态类中创建两个布尔值并将其传递给您的子列表小部件类。您也可以将状态设置为那些
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() {
return new _MainScreenState();
}
}
class _MainScreenState extends State<MainScreen> {
ZikirHistoryBloc zikirHistoryBloc;
int selectedValue = 1;
//you don't have to declare false as bool is initialised false by default
bool showText1 = false;
bool showText2 = false;
@override
Widget build(BuildContext context) {
return Scaffold(
...
Expanded(
child: ButtonMenuWidget(
image: "assets/images/zikir/button-text1.png",
title: translations.text("button_show_hide_text1"),
subtitle: point,
onTap: () {
setState(){
showText1 = !showText1;
}
}
)
),
Expanded(
child: ButtonMenuWidget(
image: "assets/images/home/button-text2.png",
title: translations.text("button_show_hide_text2"),
subtitle: dzikir,
onTap: () {
setState(){
showText2 = !showText2;
}
}
)
),
...
this.HistoriesWidget(),
...
}//::end of Widget build
...
Widget HistoriesWidget() {
return StreamBuilder(
stream: zikirHistoryBloc.dzikirHistoriesStream,
builder: (BuildContext ctx, AsyncSnapshot<List<DzikirHistory>> snapshot) {
if (snapshot.hasError) return new Text('Error: ${snapshot.error}');
if (!snapshot.hasData) return Center(child: ActivityIndicatorWidget());
if (snapshot.data.length <= 0) return Center(child: Text(translations.text("empty_data")));
return ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data.length,
primary: false,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (ctx, i) {
//**Below will call class ListCardWidget**
return ListCardWidget(
dzikirHistory: snapshot.data[i],
showText1: showText1,
showText2: showText2
);
}
);
}
);
}
...
} //
然后在您的列表卡小部件类中,将其作为参数传递并使用它
class ListCardWidget extends StatefulWidget {
DzikirHistory dzikirHistory;
bool showText1;
bool showText2;
ListCardWidget({this.dzikirHistory, this.showText1, this.showText2});
@override
_ListCardWidget createState() {
//you dont have to pass the elements to your state class
return new _ListCardWidget();
}
}
class _ListCardWidget extends State<ListCardWidget> {
//remove all these variables
//you can access all the variables directly from the stateful class
//widget.yourvariable
bool isHiddenText1;
bool isHiddenText2;
DzikirHistory dzikirHistory;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
widget.showText1 ? Container() : this.Text1Row(context),
widget.showText2 ? Container() : this.Text2Row(context),
SizedBox(height: 10,),
],
)
],
),
),
Divider(height: 2, color: Pigment.fromString(UIData.primaryColor),),
],
);
}
Widget Text1Row(context) {
return Column(
children: <Widget>[
SizedBox(height: 10,),
Row(
children: <Widget>[
SizedBox(child: Image.asset("assets/images/home/my-zikir-total.png"),height: 20, width: 20,),
SizedBox(width: 10,),
Text('Text 1 ='+getNumberFormat(widget.dzikirHistory.dzikirTotal.toString()),
style: TextStyle(
fontSize: 16,
color: Pigment.fromString(UIData.primaryColor)
),
),
],
),
],
);
}
Widget Text2Row(context) {
return Column(
children: <Widget>[
SizedBox(height: 10,),
Row(
children: <Widget>[
SizedBox(child: Image.asset("assets/images/home/my-point.png"),height: 20, width: 20,),
SizedBox(width: 10,),
Text('Text 2 ='+getNumberFormat(widget.dzikirHistory.counter.toString()),
style: TextStyle(
fontSize: 16,
color: Pigment.fromString(UIData.primaryColor)
),
),
],
),
],
);
}
getNumberFormat(String str) {
final f = new NumberFormat("#.###");
return str.replaceAll(f.symbols.GROUP_SEP, '');
}
...
}//end of class List Card Widget
推荐阅读
- css - 使用 semanti-ui-react 仅在一个网格列中滚动
- code-coverage - 了解 Eclemma 结果
- linux - 在 BASH 中创建更简洁的菜单,而不是简单地向上滚动屏幕
- c# - 扫描和更改像素 c#
- mongodb - 'mongod' 未被识别为内部或外部命令
- android - 请问如何将字符串变量传递给getStringArray
- f# - 在哪里保存 .fsi 脚本的 nuget 包?(F#)
- python - 如何有效地合并和获取不匹配条目的计数?
- php - POST Empty 无论请求如何
- velocity - 无法转换为对象 - AppSync 速度模板