英文:
How to move the DropdownSearch widget to the top of the screen above the keyboard in Flutter?
问题
以下是您要翻译的内容:
"I have a Flutter app where I'm using the dropdown_search
package to implement a multi-select dropdown
. The problem I'm facing is that when the keyboard is active, it covers the "Ok" button at the bottom of the dropdown. I want the dropdown to move to the top of the screen and show the "Ok" button above the keyboard so that the user doesn't have to manually scroll to reach it.
I've tried wrapping the DropdownSearch
widget with a SingleChildScrollView
but it doesn't seem to work. The dropdown still remains at the bottom of the screen, and the keyboard covers the "Ok" button.
Here's my code:
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});
// This widget is the root of your application.
@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;
}
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 Scaffold(
appBar: AppBar(
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}) {
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.modalBottomSheet(
modalBottomSheetProps: ModalBottomSheetProps(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
),
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,
),
),
),
style: TextStyle(color: Colors.black),
autofocus: true,
focusNode: FocusNode(canRequestFocus: true),
),
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(),
);
},
);
}
}
希望这能帮助您解决移动下拉列表以在键盘上方显示“Ok”按钮的问题。
英文:
I have a Flutter app where I'm using the dropdown_search
package to implement a multi-select dropdown
. The problem I'm facing is that when the keyboard is active, it covers the "Ok" button at the bottom of the dropdown. I want the dropdown to move to the top of the screen and show the "Ok" button above the keyboard so that the user doesn't have to manually scroll to reach it.
I've tried wrapping the DropdownSearch
widget with a SingleChildScrollView
but it doesn't seem to work. The dropdown still remains at the bottom of the screen, and the keyboard covers the "Ok" button.
Here's my code:
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});
// This widget is the root of your application.
@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;
}
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 Scaffold(
appBar: AppBar(
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}) {
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.modalBottomSheet(
modalBottomSheetProps: ModalBottomSheetProps(
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
),
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,
),
),
),
style: TextStyle(color: Colors.black),
autofocus: true,
focusNode: FocusNode(canRequestFocus: true),
),
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(),
);
},
);
}
}
I would appreciate any help or suggestions on how to achieve the desired behavior of moving the dropdown to the top of the screen and showing the "Ok" button above the keyboard.
答案1
得分: 1
可以通过将 PopupPropsMultiSelection.modalBottomSheet
替换为 PopupPropsMultiSelection.bottomSheet
来简单实现。
英文:
It can simply achieve by replacing
PopupPropsMultiSelection.modalBottomSheet
to
PopupPropsMultiSelection.bottomSheet
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论