首页 > 解决方案 > Flutter showModalBottomSheet 不改变状态需要重新打开才能看到变化

问题描述

我正在显示 showModalBottomSheet 问题是它没有改变状态我需要关闭 showModalBottomSheet 并再次打开它以查看更改。这是我的代码

List sort = [
  {'CatID': 0, 'Name': 'Trending'},
  {'CatID': 1, 'Name': 'Newest'},
  {'CatID': 2, 'Name': 'Lowset Price'},
  {'CatID': 3, 'Name': 'Highest Price'},
];

class BrowserCategoryPage2 extends StatefulWidget {
  final subCategory;
  const BrowserCategoryPage2({Key key, @required this.subCategory})
      : super(key: key);

  @override
  _BrowserCategoryPage2State createState() => _BrowserCategoryPage2State();
}

class _BrowserCategoryPage2State extends State<BrowserCategoryPage2> {
  var items = {'Items': []};
  int dateindex;
  bool showNotAvail = false;
  @override
  void initState() {
    super.initState();

    print('browse subcategory');
    print(widget.subCategory);

    widget.subCategory.forEach((subcategory) {
      items['Items'].addAll(subcategory['Items']);
    });
    print(items);
    print('sada');
  }

  int currentindex = 0;
  int sortindex = 0;

  @override
  Widget build(BuildContext context) {
    double Height = MediaQuery.of(context).size.height;
    double Width = MediaQuery.of(context).size.width;



    return Scaffold(
      body: Container(
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              SideInAnimation(
                2,
                child: Align(
                  alignment: Alignment.topLeft,
                  child: Padding(
                    padding: const EdgeInsets.symmetric(
                        horizontal: 18.0, vertical: 18),
                    child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Text(
                            'Products',
                            style: Theme.of(context).textTheme.headline3,
                          ).tr(),
                          IconButton(
                            icon: Icon(
                              FlutterIcons.filter_fea,
                              color: Theme.of(context).primaryColor,
                            ),
                            onPressed: () {
                              OpenFilter(context);
                            },
                          ),
                        ]),
                  ),
                ),
              ),
              SizedBox(height: 10.0),
            ],
          ),
        ),
      ),
    );
  }
  
  OpenFilter(BuildContext context){
    return showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) {
          double Height = MediaQuery.of(context).size.height;
          double Width = MediaQuery.of(context).size.width;


          final SortWidget = <Widget>[]; // Here we defined a list of widget!

          for (int i = 0; i < sort.length; i++) {
            SortWidget.add(
              GestureDetector(
                onTap: () {
                  setState(() {
                    // set current index!
                    sortindex = i;
                    print(sortindex);
                  });
                },
                child: Container(
                  height: Height * 0.04,
                  width: Width * 0.2,
                  decoration: BoxDecoration(
                      color: sortindex == i ? Color(0xff04385f) : Colors.white,
                      border: Border.all(
                          color:
                          sortindex == i ? Color(0xff04385f) : Colors.grey[500]),
                      borderRadius: BorderRadius.all(Radius.circular(10))),
                  child: Center(
                      child: Text(
                        sort[i]['Name'],
                        textAlign: TextAlign.center,
                        style: TextStyle(
                            fontSize: 9,
                            color: sortindex == i ? Colors.white : Colors.grey[500],
                            fontFamily: 'UbuntuRegular'),
                      )),
                ),
              ),
            );
          }

          return Container(
            decoration: BoxDecoration(
                borderRadius: new BorderRadius.only(
                    topLeft:
                    const Radius.circular(10.0),
                    topRight:
                    const Radius.circular(10.0))),
            child: new Column(
              children: [
                Container(
                  width: double.infinity,
                  height: Height * 0.055,
                  decoration: BoxDecoration(
                      color: Color(0xfff7f7f7)),
                  child: Center(
                    child: RichText(
                      text: new TextSpan(
                        style: new TextStyle(
                          fontSize: 14.0,
                          color: Colors.black,
                        ),
                        children: <TextSpan>[
                          new TextSpan(
                              text: 'Sort & ',
                              style: new TextStyle(
                                  fontSize: 18,
                                  fontFamily:
                                  'UbuntuBold')),
                          new TextSpan(
                              text: 'Filter',
                              style: TextStyle(
                                fontSize: 18,
                                fontFamily:
                                'UbuntuMedium',
                              )),
                        ],
                      ),
                    ),
                  ),
                ),
                SizedBox(
                  height: Height * 0.01,
                ),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 13, bottom: 13),
                  child: Align(
                    alignment: Alignment.centerLeft,
                    child: RichText(
                      text: new TextSpan(
                        // Note: Styles for TextSpans must be explicitly defined.
                        // Child text spans will inherit styles from parent
                        style: new TextStyle(
                          fontSize: 14.0,
                          color: Colors.black,
                        ),
                        children: <TextSpan>[
                          new TextSpan(
                              text: 'Sort ',
                              style: new TextStyle(
                                  fontSize: 16,
                                  fontFamily:
                                  'UbuntuBold')),
                          new TextSpan(
                              text: 'By',
                              style: TextStyle(
                                fontSize: 16,
                                fontFamily:
                                'UbuntuMedium',
                              )),
                        ],
                      ),
                    ),
                  ),
                ),
                Row(
                  mainAxisAlignment:
                  MainAxisAlignment.spaceAround,
                  children: SortWidget,
                ),
                Padding(
                  padding: const EdgeInsets.only(
                      left: 13, right: 13, top: 13),
                  child: Divider(
                    color: Colors.grey,
                    thickness: 1,
                  ),
                ),
                SizedBox(
                  height: Height * 0.01,
                ),

                Padding(
                  padding: const EdgeInsets.only(
                      left: 10, right: 10, top: 20),
                  child: Row(
                    mainAxisAlignment:
                    MainAxisAlignment
                        .spaceBetween,
                    children: [
                      Container(
                        height: Height * 0.06,
                        width: Width * 0.57,
                        decoration: BoxDecoration(
                          color: Color(0xff04385f),
                          borderRadius:
                          BorderRadius.only(
                              topLeft:
                              Radius.circular(
                                  12),
                              topRight:
                              Radius.circular(
                                  12),
                              bottomLeft:
                              Radius.circular(
                                  12),
                              bottomRight:
                              Radius.circular(
                                  12)),
                        ),
                        child: Center(
                            child: Text(
                              'Apply Filters',
                              style: TextStyle(
                                  fontSize: 15,
                                  fontWeight:
                                  FontWeight.bold,
                                  fontFamily:
                                  'UbuntuRegular',
                                  color: Colors.white),
                            )),
                      ),
                      Container(
                        height: Height * 0.06,
                        width: Width * 0.3,
                        decoration: BoxDecoration(
                          border: Border.all(
                              color: Colors.grey),
                          color: Colors.white,
                          borderRadius:
                          BorderRadius.only(
                              topLeft:
                              Radius.circular(
                                  12),
                              topRight:
                              Radius.circular(
                                  12),
                              bottomLeft:
                              Radius.circular(
                                  12),
                              bottomRight:
                              Radius.circular(
                                  12)),
                        ),
                        child: Center(
                            child: Text(
                              'Reset',
                              style: TextStyle(
                                  fontSize: 15,
                                  fontWeight:
                                  FontWeight.bold,
                                  fontFamily:
                                  'UbuntuRegular',
                                  color:
                                  Color(0xff04385f)),
                            )),
                      ),
                    ],
                  ),
                )
              ],
            ),
          );
        });
  }
}

您可以看到我只是在单击时更改容器的颜色。它正在改变排序索引的索引,但问题是它没有改变状态。意思是如果我关闭并打开底部表格,那么我可以看到更改。

标签: flutterdart

解决方案


setState({})如果flutter BottomSheet 作为一个小部件工作,那么bottomSheet 有自己的状态,当您调用父类时不会刷新数据。

为此,您需要使用 StatefulBuilder 来刷新 bottomSheet 的内容,例如:

await showModalBottomSheet(
        context: context,
        builder: (BuildContext bc) {
          return StatefulBuilder(builder: (BuildContext context, StateSetter state) {
            return Container();
          });
        });

请用以下解决方案替换您的方法,它将正常工作:

OpenFilter(BuildContext context) {
    return showModalBottomSheet<void>(
        context: context,
        builder: (BuildContext context) {
          return StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
            double Height = MediaQuery.of(context).size.height;
            double Width = MediaQuery.of(context).size.width;

            final SortWidget = <Widget>[]; // Here we defined a list of widget!

            for (int i = 0; i < sort.length; i++) {
              SortWidget.add(
                GestureDetector(
                  onTap: () {
                    setState(() {
                      // set current index!
                      sortindex = i;
                      print(sortindex);
                    });
                  },
                  child: Container(
                    height: Height * 0.04,
                    width: Width * 0.2,
                    decoration: BoxDecoration(
                        color: sortindex == i ? Color(0xff04385f) : Colors.white,
                        border: Border.all(color: sortindex == i ? Color(0xff04385f) : Colors.grey[500]),
                        borderRadius: BorderRadius.all(Radius.circular(10))),
                    child: Center(
                        child: Text(
                      sort[i]['Name'],
                      textAlign: TextAlign.center,
                      style: TextStyle(
                          fontSize: 9,
                          color: sortindex == i ? Colors.white : Colors.grey[500],
                          fontFamily: 'UbuntuRegular'),
                    )),
                  ),
                ),
              );
            }
            return Container(
              decoration: BoxDecoration(
                  borderRadius: new BorderRadius.only(
                      topLeft: const Radius.circular(10.0), topRight: const Radius.circular(10.0))),
              child: new Column(
                children: [
                  Container(
                    width: double.infinity,
                    height: Height * 0.055,
                    decoration: BoxDecoration(color: Color(0xfff7f7f7)),
                    child: Center(
                      child: RichText(
                        text: new TextSpan(
                          style: new TextStyle(
                            fontSize: 14.0,
                            color: Colors.black,
                          ),
                          children: <TextSpan>[
                            new TextSpan(text: 'Sort & ', style: new TextStyle(fontSize: 18, fontFamily: 'UbuntuBold')),
                            new TextSpan(
                                text: 'Filter',
                                style: TextStyle(
                                  fontSize: 18,
                                  fontFamily: 'UbuntuMedium',
                                )),
                          ],
                        ),
                      ),
                    ),
                  ),
                  SizedBox(
                    height: Height * 0.01,
                  ),
                  Padding(
                    padding: const EdgeInsets.only(left: 13, bottom: 13),
                    child: Align(
                      alignment: Alignment.centerLeft,
                      child: RichText(
                        text: new TextSpan(
                          // Note: Styles for TextSpans must be explicitly defined.
                          // Child text spans will inherit styles from parent
                          style: new TextStyle(
                            fontSize: 14.0,
                            color: Colors.black,
                          ),
                          children: <TextSpan>[
                            new TextSpan(text: 'Sort ', style: new TextStyle(fontSize: 16, fontFamily: 'UbuntuBold')),
                            new TextSpan(
                                text: 'By',
                                style: TextStyle(
                                  fontSize: 16,
                                  fontFamily: 'UbuntuMedium',
                                )),
                          ],
                        ),
                      ),
                    ),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: SortWidget,
                  ),
                  Padding(
                    padding: const EdgeInsets.only(left: 13, right: 13, top: 13),
                    child: Divider(
                      color: Colors.grey,
                      thickness: 1,
                    ),
                  ),
                  SizedBox(
                    height: Height * 0.01,
                  ),
                  Padding(
                    padding: const EdgeInsets.only(left: 10, right: 10, top: 20),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceBetween,
                      children: [
                        Container(
                          height: Height * 0.06,
                          width: Width * 0.57,
                          decoration: BoxDecoration(
                            color: Color(0xff04385f),
                            borderRadius: BorderRadius.only(
                                topLeft: Radius.circular(12),
                                topRight: Radius.circular(12),
                                bottomLeft: Radius.circular(12),
                                bottomRight: Radius.circular(12)),
                          ),
                          child: Center(
                              child: Text(
                            'Apply Filters',
                            style: TextStyle(
                                fontSize: 15,
                                fontWeight: FontWeight.bold,
                                fontFamily: 'UbuntuRegular',
                                color: Colors.white),
                          )),
                        ),
                        Container(
                          height: Height * 0.06,
                          width: Width * 0.3,
                          decoration: BoxDecoration(
                            border: Border.all(color: Colors.grey),
                            color: Colors.white,
                            borderRadius: BorderRadius.only(
                                topLeft: Radius.circular(12),
                                topRight: Radius.circular(12),
                                bottomLeft: Radius.circular(12),
                                bottomRight: Radius.circular(12)),
                          ),
                          child: Center(
                              child: Text(
                            'Reset',
                            style: TextStyle(
                                fontSize: 15,
                                fontWeight: FontWeight.bold,
                                fontFamily: 'UbuntuRegular',
                                color: Color(0xff04385f)),
                          )),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            );
          });
        });
  }

推荐阅读