英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论