Flutter-如何在另一个类上显示/隐藏小部件

时间:2019-07-10 01:50:30

标签: flutter dart widget flutter-layout

我有2个班级,第一个是Main Widget Screen,第二个是List Card。在View Perspective中,Main Widget Screen类包含List Widget类中的List Card Widget,如下图所示:

Flutter UI Widget (Show/Hide) Concept View

List Card小部件上,每个列表都有2个文本:Text1Text2

还有两个按钮:this monthlast monthList Card Widget上的数据将根据 Bloc Stream ZikirHistoryBloc.onChangeTab()刷新。默认值为this month

我想要实现的是:

  

如何通过Text1上的按钮显示/隐藏(开/关)Text2Main 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 解决方案不起作用,因为当我单击上个月时,数据不会刷新(以前是正常的)。同样,仅当我单击上个月或本月按钮时,显示/隐藏才起作用。

1 个答案:

答案 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