创建一个要在其中执行Flutter-FireBase搜索的屏幕。但是“可见性切换”无法正常工作。
所需的切换行为:单击TextForm字段时,前缀图标和结果卡应可见。单击“前缀”图标(后退箭头)后,“结果列表”(卡片)和前缀图标本身应变为不可见,并且TextField应失去焦点。
实际行为:单击前缀图标时,结果集和前缀图标不要消失,前缀图标保留在那里,结果集变为不可见,但在TextFormField下占用了一些空间

class AddAppointmentWidget extends StatefulWidget {
  @override
  _AddAppointmentWidgetState createState() => _AddAppointmentWidgetState();
}

class _AddAppointmentWidgetState extends State<AddAppointmentWidget> {
  bool searchbartapped = false;
  var queryResultSet = [];
  var tempSearchStore = [];

// Search Function
  initiateSearch(value) {
    //body
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: [
        SizedBox(
          height: 15,
        ),
        Padding(
          padding: const EdgeInsets.all(18.0),
          child: Text('Search',
              style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
        ),
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            children: [
              Expanded(
                flex: 5,
                child: TextFormField(
                    style: TextStyle(color: Color(0xff2a2a2a), fontSize: 18),
                    keyboardType: TextInputType.name,
                    onChanged: (value) {
                      initiateSearch(value);
                    },
                    onTap: () {
                      setState(() {
                        searchbartapped = true;
                      });
                    },
                    cursorColor: Color(0xff2a2a2a),
                    cursorWidth: 1.5,
                    decoration: InputDecoration(
                        hintText: "Search by Name",
                        prefixIcon: Visibility(
                          visible: searchbartapped,
                          child: IconButton(
                              icon: Icon(Icons.arrow_back),
                              color: Colors.black54,
                              onPressed: () {
                                setState(() {
                                  searchbartapped = !searchbartapped;
                                  queryResultSet = [];
                                  tempSearchStore = [];
                                });
                                FocusScope.of(context).unfocus();
                              }),
                        ),
                        )),
              ),
            ],
          ),
        ),
        Visibility(
          visible: searchbartapped,
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: ListView(
                padding: EdgeInsets.all(5.0),
                primary: false,
                shrinkWrap: true,
                children: tempSearchStore.map((element) {
                  print(element['name']);
                  return buildResult(context, element);
                }).toList()),
          ),
        ),
      ],
    );
  }
}
注意 buildResult小部件运行正常。
问题仅在于可见性切换

最佳答案

问题:当您点击prefixIcon时:

调用

  • onPressed,将searchbartapped设置为所需的false
  • 也称为onTapTextFormField方法(因为prefixIcon在其中),将searchbartapped设置为true

  • 因此,您要防止发生第二个事件。我试图防止通知使树冒泡,但我不能。所以我最终要做的是多手动一些,但效果也一样。
    解决方案:添加一个变量(例如hideSearchTapped),该变量在调用prefixIcon时设置为true。然后,当您调用onTapTextFormField方法时,请检查以下变量:
  • 如果hideSearchTapped为true,请将其设置为false
  • 像更改
  • 一样更改searchbartapped
    这是一个工作示例:
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() async {
      runApp(
        MaterialApp(
          home: Scaffold(
            body: new AddAppointmentWidget(),
          ),
        ),
      );
    }
    
    class AddAppointmentWidget extends StatefulWidget {
      @override
      _AddAppointmentWidgetState createState() => _AddAppointmentWidgetState();
    }
    
    class _AddAppointmentWidgetState extends State<AddAppointmentWidget> {
      bool searchbartapped = false;
      bool hideSearchTapped = false;
      var queryResultSet = [];
      var tempSearchStore = [];
    
    // Search Function
      initiateSearch(value) {
        //body
      }
    
      @override
      Widget build(BuildContext context) {
        return ListView(
          children: [
            SizedBox(
              height: 15,
            ),
            Padding(
              padding: const EdgeInsets.all(18.0),
              child: Text('Search', style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold)),
            ),
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                children: [
                  Expanded(
                    flex: 5,
                    child: TextFormField(
                        style: TextStyle(color: Color(0xff2a2a2a), fontSize: 18),
                        keyboardType: TextInputType.name,
                        onChanged: (value) {
                          initiateSearch(value);
                        },
                        onTap: () {
                          setState(() {
                            if (hideSearchTapped) {
                              hideSearchTapped = false;
                            } else {
                              searchbartapped = true;
                            }
                          });
                        },
                        cursorColor: Color(0xff2a2a2a),
                        cursorWidth: 1.5,
                        decoration: InputDecoration(
                          hintText: "Search by Name",
                          prefixIcon: Visibility(
                            visible: searchbartapped,
                            child: IconButton(
                                icon: Icon(Icons.arrow_back),
                                color: Colors.black54,
                                onPressed: () {
                                  hideSearchTapped = true;
                                  searchbartapped = !searchbartapped;
                                  queryResultSet = [];
                                  tempSearchStore = [];
                                  setState(() {
                                  });
                                  FocusScope.of(context).unfocus();
                                  return true;
                                }),
                          ),
                        )),
                  ),
                ],
              ),
            ),
            Visibility(
              visible: searchbartapped,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: ListView(
                    padding: EdgeInsets.all(5.0),
                    primary: false,
                    shrinkWrap: true,
                    children: tempSearchStore.map((element) {
                      print(element['name']);
                    }).toList()),
              ),
            ),
          ],
        );
      }
    }
    
    注意:您应该use lowerCamelCase to name your variable。因此searchbartapped将变成searchBarTapped

    10-08 07:19