mirror of https://github.com/flutter/samples.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
215 lines
7.4 KiB
215 lines
7.4 KiB
5 years ago
|
// Copyright 2020, the Flutter project authors. Please see the AUTHORS file
|
||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||
|
// BSD-style license that can be found in the LICENSE file.
|
||
|
|
||
|
import 'package:flutter/material.dart';
|
||
|
import 'package:intl/intl.dart' as intl;
|
||
|
|
||
|
class FormWidgetsDemo extends StatefulWidget {
|
||
|
@override
|
||
|
_FormWidgetsDemoState createState() => _FormWidgetsDemoState();
|
||
|
}
|
||
|
|
||
|
class _FormWidgetsDemoState extends State<FormWidgetsDemo> {
|
||
|
final _formKey = GlobalKey<FormState>();
|
||
|
String title = '';
|
||
|
String description = '';
|
||
|
DateTime date = DateTime.now();
|
||
|
double maxValue = 0;
|
||
|
bool brushedTeeth = false;
|
||
|
bool enableFeature = false;
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Scaffold(
|
||
|
appBar: AppBar(
|
||
|
title: Text('Form widgets'),
|
||
|
),
|
||
|
body: Form(
|
||
|
key: _formKey,
|
||
|
child: Scrollbar(
|
||
|
child: Align(
|
||
|
alignment: Alignment.topCenter,
|
||
|
child: Card(
|
||
|
child: SingleChildScrollView(
|
||
|
padding: EdgeInsets.all(16),
|
||
|
child: ConstrainedBox(
|
||
|
constraints: BoxConstraints(maxWidth: 400),
|
||
|
child: Column(
|
||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||
|
children: [
|
||
|
...[
|
||
|
TextFormField(
|
||
|
decoration: InputDecoration(
|
||
|
filled: true,
|
||
|
hintText: 'Enter a title...',
|
||
|
labelText: 'Title',
|
||
|
),
|
||
|
onChanged: (value) {
|
||
|
setState(() {
|
||
|
title = value;
|
||
|
});
|
||
|
},
|
||
|
),
|
||
|
TextFormField(
|
||
|
decoration: InputDecoration(
|
||
|
border: const OutlineInputBorder(),
|
||
|
filled: true,
|
||
|
hintText: 'Enter a description...',
|
||
|
labelText: 'Description',
|
||
|
),
|
||
|
onChanged: (value) {
|
||
|
description = value;
|
||
|
},
|
||
|
maxLines: 5,
|
||
|
),
|
||
|
_FormDatePicker(
|
||
|
date: date,
|
||
|
onChanged: (value) {
|
||
|
setState(() {
|
||
|
date = value;
|
||
|
});
|
||
|
},
|
||
|
),
|
||
|
Column(
|
||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: [
|
||
|
Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
|
children: [
|
||
|
Text(
|
||
|
'Estimated value',
|
||
|
style: Theme.of(context).textTheme.bodyText1,
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
Text(
|
||
|
intl.NumberFormat.currency(
|
||
|
symbol: "\$", decimalDigits: 0)
|
||
|
.format(maxValue),
|
||
|
style: Theme.of(context).textTheme.subtitle1,
|
||
|
),
|
||
|
Slider(
|
||
|
min: 0,
|
||
|
max: 500,
|
||
|
divisions: 500,
|
||
|
value: maxValue,
|
||
|
onChanged: (value) {
|
||
|
setState(() {
|
||
|
maxValue = value;
|
||
|
});
|
||
|
},
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.start,
|
||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||
|
children: [
|
||
|
Checkbox(
|
||
|
value: brushedTeeth,
|
||
|
onChanged: (checked) {
|
||
|
setState(() {
|
||
|
brushedTeeth = checked;
|
||
|
});
|
||
|
},
|
||
|
),
|
||
|
Text('Brushed Teeth',
|
||
|
style: Theme.of(context).textTheme.subtitle1),
|
||
|
],
|
||
|
),
|
||
|
Row(
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||
|
children: [
|
||
|
Text('Enable feature',
|
||
|
style: Theme.of(context).textTheme.bodyText1),
|
||
|
Switch(
|
||
|
value: enableFeature,
|
||
|
onChanged: (enabled) {
|
||
|
setState(() {
|
||
|
enableFeature = enabled;
|
||
|
});
|
||
|
},
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
].expand(
|
||
|
(widget) => [
|
||
|
widget,
|
||
|
SizedBox(
|
||
|
height: 24,
|
||
|
)
|
||
|
],
|
||
|
)
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class _FormDatePicker extends StatefulWidget {
|
||
|
final DateTime date;
|
||
|
final ValueChanged onChanged;
|
||
|
|
||
|
_FormDatePicker({
|
||
|
this.date,
|
||
|
this.onChanged,
|
||
|
});
|
||
|
|
||
|
@override
|
||
|
_FormDatePickerState createState() => _FormDatePickerState();
|
||
|
}
|
||
|
|
||
|
class _FormDatePickerState extends State<_FormDatePicker> {
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Row(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
|
children: [
|
||
|
Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
|
children: [
|
||
|
Text(
|
||
|
'Date',
|
||
|
style: Theme.of(context).textTheme.bodyText1,
|
||
|
),
|
||
|
Text(
|
||
|
intl.DateFormat.yMd().format(widget.date),
|
||
|
style: Theme.of(context).textTheme.subtitle1,
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
FlatButton(
|
||
|
child: Text('Edit'),
|
||
|
onPressed: () async {
|
||
|
var newDate = await showDatePicker(
|
||
|
context: context,
|
||
|
initialDate: widget.date,
|
||
|
firstDate: DateTime(1900),
|
||
|
lastDate: DateTime(2100),
|
||
|
);
|
||
|
|
||
|
// Don't change the date if the date picker returns null.
|
||
|
if (newDate == null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
widget.onChanged(newDate);
|
||
|
},
|
||
|
)
|
||
|
],
|
||
|
);
|
||
|
}
|
||
|
}
|