首页 > 解决方案 > Flutter - 如何在另一个类上显示/隐藏小部件

问题描述

我有 2 节课,第 1 节是Main Widget Screen,第 2 节是List Card. 在 View Perspective 中,Main Widget ScreenClass 包含List Widget来自List Card WidgetClass ,如下图所示:

Flutter UI Widget(显示/隐藏)概念视图

List CardWidget 上,每个列表都有 2 Text:Text1Text2.

此外,还有 2 个按钮:this monthlast month. data onList Card Widget将根据Bloc Stream ZikirHistoryBloc.onChangeTab()刷新。默认为this month.

我想要实现的是:

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

标签: flutterdartwidgetflutter-layout

解决方案


最好的解决方案是使用继承的 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

推荐阅读