Flutter showModalBottomSheet未改变状态,需要重新打开它以查看更改

esbemjvw  于 2023-02-20  发布在  Flutter
关注(0)|答案(3)|浏览(411)

我显示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)),
                            )),
                      ),
                    ],
                  ),
                )
              ],
            ),
          );
        });
  }
}

你可以看到我只是改变了容器的颜色,它改变了排序索引的索引,但问题是它没有改变状态,这意味着如果我关闭并打开底部的工作表,我可以看到变化。

kokeuurv

kokeuurv1#

如果flutter BottomSheet作为一个小部件工作,那么bottomSheet有自己的状态,当你调用父类的setState({})时不会刷新数据。
为此,您需要使用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)),
                          )),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            );
          });
        });
  }
c2e8gylq

c2e8gylq2#

Flutter非常擅长尽可能少地重建它的小部件。所以如果有任何常量小部件/值,它就不会重建它们。这也适用于底层表单。
如果你想让你的底层工作表通过热重启更新,你可以在底层工作表中创建一个有状态的小部件,然后它就会更新。
下面是一个例子:

class MyBottomSheet extends StatefulWidget {
  const MyBottomSheet({
    Key key,
  }) : super(key: key);

  Future<T> show<T>(BuildContext context) {
    return showModalBottomSheet<T>(
      context: context,
      isDismissible: true,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      builder: (_) => return this,
    );
  }

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

class _MyBottomSheetState extends State<MyBottomSheet> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
      height: 310,
    );
  }
}

要访问底层,可以通过MyBottomSheet().show(context);调用它

bkkx9g8r

bkkx9g8r3#

要查看使用Hot Reload对showModalBottomSheet所做的更改,只需从返回值中提取Widget。
示例:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(onPressed: (){
        showModalBottomSheet(
            context: context, builder: (context){
          return AddNoteBottomSheet();
        });
      }, child: Text('+', style: TextStyle(fontSize: 30.0),),),
      body: NotesViewBody(),
    );
  }

现在你可以看到在AddNoteBottomSheet()小部件上所做的所有修改。

相关问题