英文:
What to do when the keyboard is hiding the form?
问题
I see that you're working on a Flutter project and have shared some Dart code for translation. If you have specific parts of the code you'd like to be translated, please let me know which sections you'd like to translate, and I'll provide translations for those parts.
英文:
I have this design that I'm creating on Flutter:
Here is what I managed to do so far:
I'll provided you my code and I ll explain it and finally I'll try to explain the error that I'm having. First here is my code:
class CheckoutPage extends StatefulWidget {
const CheckoutPage({super.key});
@override
State<CheckoutPage> createState() => _CheckoutPageState();
}
class _CheckoutPageState extends State<CheckoutPage>
with TickerProviderStateMixin {
Map<String, bool> isActive = {
'Quantity': true,
'Payment': false,
'Review': false,
};
Map<String, bool> isDone = {
'Quantity': false,
'Payment': false,
'Review': false,
};
@override
Widget build(BuildContext context) {
order = ModalRoute.of(context)!.settings.arguments as Order;
final PageController pageViewController = PageController();
final double height = MediaQuery.of(context).size.height;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
final TextEditingController nameController = TextEditingController();
final TextEditingController phoneNumberController = TextEditingController();
final TextEditingController addressController = TextEditingController();
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
children: [
Column(
children: [
SizedBox(
height: height * 0.16,
child: PageViewIndicator(isActive: isActive, isDone: isDone),
),
SizedBox(
height: height * 0.84,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 18,
),
child: PageView(
controller: pageViewController,
children: [
QuantityStepWidget(
formKey: formKey,
addressController: addressController,
nameController: nameController,
phoneNumberController: phoneNumberController,
),
const PaymentStepWidget(),
const ReviewStepWidget(),
],
),
),
),
],
),
const BackButtonWidget(),
],
),
);
}
}
This code is mainly composed of a Scaffold
, it's child is a Stack
that stacks a back button (BackButton
) on tap of a Column
. This column has two containers SizedBox
; the first one takes 16% of the height of the screen, and the second one takes 84% which makes a total of 100%. Inside the first SizedBox
I defined a PageViewIndicator
widget which is a Container
that holds a Row
that holds 3 HeadingPageViewItemWidget
like this:
class PageViewIndicator extends StatelessWidget {
final Map<String, bool> isActive;
final Map<String, bool> isDone;
const PageViewIndicator({
super.key,
required this.isActive,
required this.isDone,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: AppColors.borderColor),
),
),
child: Padding(
padding: const EdgeInsets.only(left: 8.0, right: 8.0, bottom: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
HeadingPageViewItemWidget(
number: '1',
title: 'Quantity',
isActive: isActive['Quantity']!,
isDone: isDone['Quantity']!,
),
HeadingPageViewItemWidget(
number: '2',
title: 'Payment',
isActive: isActive['Payment']!,
isDone: isDone['Payment']!,
),
HeadingPageViewItemWidget(
number: '3',
title: 'Review',
isActive: isActive['Review']!,
isDone: isDone['Review']!,
),
],
),
),
);
}
}
The HeadingPageViewItemWidget
is another Row
that holds a CircleAvatar
and a Text
widget, like this:
class HeadingPageViewItemWidget extends StatelessWidget {
final String number;
final String title;
final bool isDone;
final bool isActive;
const HeadingPageViewItemWidget({
Key? key,
required this.number,
required this.title,
this.isDone = false,
this.isActive = false,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
width: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
CircleAvatar(
backgroundColor: _getColor(isDone: isDone, isActive: isActive),
radius: 15,
child: _getIconOrNumber(isDone),
),
SizedBox(
width: 60,
child: Text(title, style: kCaption0),
),
],
),
);
}
}
Inside the second SizedBox
I have defined a PageView
that has 3 children, QuantityStepWidget
, PaymentStepWidget
and ReviewStepWidget
, these last two are just PlaceHolder
s for the moment. The QuantityStepWidget
is defined like this:
class QuantityStepWidget extends StatelessWidget {
final GlobalKey<FormState> formKey;
final TextEditingController nameController;
final TextEditingController phoneNumberController;
final TextEditingController addressController;
const QuantityStepWidget(
{super.key,
required this.formKey,
required this.nameController,
required this.phoneNumberController,
required this.addressController});
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.8,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
fit: FlexFit.loose,
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.05,
child: const TitleWidget(title: 'Quantity')),
),
Flexible(
flex: 3,
fit: FlexFit.loose,
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.35,
width: double.infinity,
child: MedicationCheckoutQuantityWidget(order: order),
),
),
Flexible(
flex: 3,
fit: FlexFit.loose,
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.4,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Confirm your information',
style: kH3TitleStyle,
),
const SizedBox(height: 10),
Flexible(
fit: FlexFit.loose,
child: SizedBox(
height: 200,
child: Form(
key: formKey,
child: Column(
children: [
Flexible(
flex: 1,
fit: FlexFit.loose,
child:
TextFormFieldUserInformationsConfirmationWidget(
type: FormType.name,
controller: nameController,
),
),
Flexible(
flex: 1,
fit: FlexFit.loose,
child:
TextFormFieldUserInformationsConfirmationWidget(
type: FormType.phoneNumber,
controller: phoneNumberController,
),
),
Flexible(
flex: 1,
fit: FlexFit.loose,
child:
TextFormFieldUserInformationsConfirmationWidget(
type: FormType.address,
controller: addressController,
),
),
],
),
),
),
),
const SizedBox(height: 20),
ButtonWidget(
onPressed: () {
print('lol');
if (formKey.currentState!.validate()) {
print(nameController.text);
print(phoneNumberController.text);
print(addressController.text);
}
},
text: 'Confirm'),
],
),
),
)
],
),
),
);
}
}
It consists of a SingleChildScrollView
and inside it there is a Column
which holds thre Flexible
widgets; the first one is the 'Quantity' title, the second one is the two cards of the medication name and quantity, and the third one is the form.
What I want is to make the form go up when the keyboard gets triggered, but it doesn't want to do that, all it does is to show the keyboard and then close it instanly, and it doesn't give me the time to add text, as soon as the keyboard opens it closes
答案1
得分: 1
在你的构建方法之外放置这两个:
final double height = MediaQuery.of(context).size.height;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
获取更多信息,请访问此线程:StackOverflow答案
英文:
Put These Two outside of your build method:
final double height = MediaQuery.of(context).size.height;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
For more information, visit this thread: StackOverflow answer
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论