英文:
How to hide the AppBar back button when a DropdownSearch widget is open in Flutter?
问题
以下是您要翻译的代码部分:
// 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();
});
}
});
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),
),
如果需要进一步帮助,请告诉我。
英文:
I am developing an application in Flutter where I have a DropdownSearch widget and an AppBar with a back button. I want the back button to be hidden when the dropdown is opened and shown again when the dropdown is closed.
I attempted to achieve this by using a FocusNode and adding a listener to it. When the DropdownSearch is focused (opened), I set a showBackButton variable to false, and when the DropdownSearch loses focus (is closed), I set showBackButton back to true. The FocusNode is then passed to the DropdownSearch widget.
Here's the code snippet:
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(),
);
},
);
}
}
The showBackButton variable is defined in a GetxController and is used to control the visibility of the back button. When its value is changed, I call update() to rebuild the widgets that use showBackButton.
However, this solution does not work as expected. The back button does not hide when the dropdown is opened.

How can I hide the AppBar back button when the DropdownSearch widget is open? Any help would be appreciated.
答案1
得分: 1
首先,当你使用Getx时,请不要使用setState。
然后,通过在变量后面加上.obs来使你的showBackButton值可观察。
接着,用Getx提供的Obx小部件包裹你的AppBar。
在Obx小部件内部像这样使用变量:
controller.showBackButton.value ? BackButton() : null
另外,请检查一下你的变量是否在更新。
英文:
Bro 1st of all don't use setState when you are using Getx.
And then make your showBackButton value observable by .obs from Getx.
and then wrap your AppBar with the Obx widget provided by Getx.
use the variable inside the Obx widget like this
controller.showBackButton.value ? BackButton() : null
Also, please check whether your variable is updating or not.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论