我有这个设计,是我在Flutter度上创造的:
到目前为止,我做到了以下几点:
我将向您提供我的代码,并对其进行解释,最后我将try 解释我遇到的错误.首先是我的代码:
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(),
],
),
);
}
}
这个代码主要由Scaffold
组成,它的子代是Stack
,它在Column
的点击上堆叠了一个后退按钮(BackButton
).该柱具有两个容器SizedBox
;第一个容器占据屏幕高度的16%,第二个容器占据84%,总计为Scaffold
%.在第一个SizedBox
中,我定义了一个PageViewIndicator
小部件,它是一个Container
,其中包含一个Row
,其中包含3个HeadingPageViewItemWidget
,如下所示:
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']!,
),
],
),
),
);
}
}
HeadingPageViewItemWidget
是另一个包含CircleAvatar
和Text
小部件的Row
,如下所示:
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),
),
],
),
);
}
}
在第二个SizedBox
中,我定义了一个PageView
,它有3个子元素,QuantityStepWidget
、PaymentStepWidget
和ReviewStepWidget
,最后两个暂时只是PlaceHolder
.QuantityStepWidget
的定义如下:
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'),
],
),
),
)
],
),
),
);
}
}
它由一个SingleChildScrollView
组成,里面有一个Column
,其中包含三个Flexible
个小部件;第一个是"数量"标题,第二个是药物名称和数量的两张卡片,第三个是表格.
我想要的是当键盘被触发时使窗体上升,但它不想这样做,它所做的只是显示键盘,然后立即关闭它,它没有时间添加文本,一旦键盘打开它关闭