颤振可见性切换未按预期工作



创建一个屏幕,我想在其中执行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:时

调用
  1. onPressed,将searchbartapped设置为false,这正是您想要的
  2. TextFormFieldonTap方法也被调用(因为prefixIcon在其中(,将searchbartapped设置为true

所以你想要的是防止第二个事件发生。我试图阻止通知在树上冒泡,但我做不到。所以我最终做的是更多的手动操作,但效果也一样。

解决方案:添加一个变量(例如hideSearchTapped(,该变量在调用prefixIcon时设置为true。然后,当调用TextFormFieldonTap方法时,检查此变量:

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

注意:您应该使用lowerCamelCase来命名您的变量。因此CCD_ 16将变为CCD_ 17。

最新更新