我有2个班级,第一个是Main Widget Screen
,第二个是List Card
。在View Perspective中,Main Widget Screen
类包含List Widget
类中的List Card Widget
,如下图所示:
在List Card
小部件上,每个列表都有2个文本:Text1
和Text2
。
还有两个按钮:this month
和last month
。 List 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 解决方案不起作用,因为当我单击上个月时,数据不会刷新(以前是正常的)。同样,仅当我单击上个月或本月按钮时,显示/隐藏才起作用。
答案 0 :(得分:2)
最好的解决方案是使用继承的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