[英]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
:
onPressed
is called, setting searchbartapped
to false
which is what you want. onPressed
被调用时,设置searchbartapped
到false
这是你想要的。onTap
method of your TextFormField
is also called (since prefixIcon
is inside it), setting searchbartapped
to true
.该onTap
你的方法TextFormField
也被称为(因为prefixIcon
是里面),设置searchbartapped
至true
。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:然后当你的TextFormField
的onTap
方法被调用时,检查这个变量:
hideSearchTapped
is true, set it to false如果hideSearchTapped
为 true,则将其设置为 falsesearchbartapped
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.