我正在用Flutter开发一个应用程序,其中有一个DropdownSearch
小部件和一个带有后退按钮的AppBar。我希望在下拉菜单打开时隐藏后退按钮,并在下拉菜单关闭时再次显示。
我试图通过使用FocusNode
并向其添加一个侦听器来实现这一点。当DropdownSearch
被聚焦(打开)时,我将showBackButton
变量设置为false
,当DropdownSearch
失去聚焦(关闭)时,我将showBackButton
设置回true
。FocusNode
随后被传递给DropdownSearch
小工具。
下面是代码片段:
import 'package:flutter/material.dart';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:get/get.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'MultiSelectDropDown',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'MultiSelectDropDown'),
initialBinding: QuestionnaireBinding(),
);
}
}
class QuestionnaireBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<QuestionnaireController>(() => QuestionnaireController());
}
}
class QuestionnaireController extends GetxController
with GetSingleTickerProviderStateMixin {
RxList<String> choices = <String>[].obs;
bool showBackButton = true;
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final dropdownSearchTheme = ThemeData(
colorScheme: const ColorScheme(
primary: Color(0xFF485946),
onPrimary: Colors.white,
secondary: Colors.black,
onSecondary: Colors.deepOrange,
error: Colors.transparent,
onError: Colors.transparent,
background: Colors.transparent,
onBackground: Colors.black,
brightness: Brightness.light,
onSurface: Colors.black,
surface: Colors.white,
));
@override
Widget build(BuildContext context) {
return GetBuilder<QuestionnaireController>(builder: (controller) {
return Scaffold(
appBar: AppBar(
leading: controller.showBackButton ? BackButton() : null,
// Use the new variable to control the visibility of the back button
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
const Text(
'Let\'s start choosing',
textAlign: TextAlign.center,
),
const SizedBox(
height: 30,
),
Theme(
data: dropdownSearchTheme,
child: _buildDropdownSearch(
context,
Get.find<QuestionnaireController>().choices,
dropdownCustomBuilder: _customChoice,
),
),
],
),
),
),
);
});
}
Widget _buildDropdownSearch(
BuildContext context, RxList<String> selectedChoice,
{Widget Function(BuildContext, List<String>)? dropdownCustomBuilder}) {
final controller = Get.find<QuestionnaireController>();
// Initialize FocusNode and add a listener
FocusNode _dropdownFocusNode = FocusNode();
_dropdownFocusNode.addListener(() {
if (_dropdownFocusNode.hasFocus) {
// Dropdown is opened
setState(() {
print("user opened the drop down");
controller.showBackButton = false;
controller.update();
});
} else {
// Dropdown is closed
setState(() {
print("user closed the drop down");
controller.showBackButton = true;
controller.update();
});
}
});
return DropdownSearch<String>.multiSelection(
selectedItems: selectedChoice,
items: [
"choice1",
"choice2",
"choice3",
"choice4",
"choice5",
"choice6",
"choice7",
"choice8",
"choice9",
"choice10",
"choice11"
],
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
hintText: 'pickChoice',
hintStyle: TextStyle(color: Colors.black),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: Colors.grey,
),
),
)),
dropdownBuilder: dropdownCustomBuilder,
popupProps: PopupPropsMultiSelection.bottomSheet(
searchFieldProps: TextFieldProps(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
decoration: InputDecoration(
hintText: 'Search for choice',
hintStyle: TextStyle(color: Colors.black),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide(
color: Colors.grey,
),
),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: () {
controller.choices.clear();
},
),
),
style: TextStyle(color: Colors.black),
autofocus: true,
focusNode: _dropdownFocusNode,
),
showSearchBox: true,
showSelectedItems: true,
isFilterOnline: false,
onItemAdded: (selectedItems, addedItem) {
selectedChoice.add(addedItem);
},
onItemRemoved: (selectedItems, removedItem) {
selectedChoice.remove(removedItem);
},
),
);
}
Widget _customChoice(BuildContext context, List<String> selectedItems) {
final controller = Get.find<QuestionnaireController>();
return GetBuilder<QuestionnaireController>(
initState: (_) {},
builder: (_) {
if (selectedItems.isEmpty) {
return Text("Pick a choice");
}
return Wrap(
spacing: 2,
runSpacing: -10,
children: selectedItems.map((e) {
return Chip(
backgroundColor: Colors.lightGreen,
label: Text(
e.toString().trim(),
),
onDeleted: () {
selectedItems.remove(e.toString().trim());
controller.choices.remove(e.toString().trim());
},
);
}).toList(),
);
},
);
}
}
字符串showBackButton
变量在GetxController
中定义,用于控制后退按钮的可见性。当它的值改变时,我调用update()
来重建使用showBackButton
的小部件。
但是,此解决方案并不能按预期工作。当下拉式清单开启时,上一页按钮不会隐藏。
的数据
如何在DropdownSearch
小工具打开时隐藏AppBar后退按钮?如果你能帮忙的话,我会很感激的。
1条答案
按热度按时间wa7juj8i1#
首先,当你使用
Getx
时,不要使用setState
。然后让你的
showBackButton
值可以被来自Getx的.obs
观察到。然后使用Getx提供的
Obx
小部件 Package 您的AppBar
。像这样使用Obx小部件中的变量
字符串
另外,请检查您的变量是否正在更新。