简体   繁体   English

Flutter 可见性切换未按预期工作

[英]Flutter Visibility Toggle not working as expected

Creating a Screen where I want to perform Flutter-FireBase Searching.But Visibility Toggle is not working as desired.创建一个我想在其中执行 Flutter-FireBase Searching 的屏幕。但是 Visibility Toggle 没有按预期工作。
Desired Toggle Behaviour : When clicked on TextForm field , prefix icon and result card should be visible.所需的切换行为:当单击 TextForm 字段时,前缀图标和结果卡应该是可见的。 Upon Clicking the Prefix Icon(Back Arrow) , Result List (Card) and the prefix icon itself should become invisible and TextField should unfocus .单击前缀图标(后退箭头)后,结果列表(卡片)和前缀图标本身应该不可见,并且 TextField 应该不聚焦。
Actual Behaviour : On clicking the prefix icon , Result set and prefix icon don't disappear , Prefix icon remains there and result set becomes invisible but occupies some space beneath the TextFormField实际行为:单击前缀图标时,结果集和前缀图标不会消失,前缀图标保留在那里,结果集变得不可见,但会占用 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()),
          ),
        ),
      ],
    );
  }
}

Note The buildResult widget is working perfectly fine.注意buildResult 小部件运行良好。 Problem is only with the visibilty toggle问题仅在于可见性切换

The issue: When you tap the prefixIcon :问题:当您点击prefixIcon

  1. onPressed is called, setting searchbartapped to false which is what you want. onPressed被调用时,设置searchbartappedfalse这是你想要的。
  2. The onTap method of your TextFormField is also called (since prefixIcon is inside it), setting searchbartapped to true .onTap你的方法TextFormField也被称为(因为prefixIcon是里面),设置searchbartappedtrue

So what you want is to prevent the second event from happening.所以你想要的是防止第二个事件发生。 I tried to prevent the notification from bubbling up the tree but I couldn't.我试图阻止通知在树上冒泡,但我做不到。 So what I ended up doing is a bit more manual but works just as well.所以我最终做的是更多的手动操作,但效果也很好。

Solution: Add a variable (for example hideSearchTapped ) which is set to true when the prefixIcon is called.解决方案:添加一个变量(例如hideSearchTapped ),该prefixIcon在调用prefixIcon时设置为 true。 Then when the onTap method of your TextFormField is called, check this variable:然后当你的TextFormFieldonTap方法被调用时,检查这个变量:

  • If hideSearchTapped is true, set it to false如果hideSearchTapped为 true,则将其设置为 false
  • Else change searchbartapped as you did其他更改searchbartapped像你一样

Here is a working example:这是一个工作示例:

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()),
          ),
        ),
      ],
    );
  }
}

Note: you should use lowerCamelCase to name your variable .注意:您应该使用lowerCamelCase 来命名您的变量 So searchbartapped would become searchBarTapped .所以searchbartapped将成为searchBarTapped

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM