mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 13:58:47 +00:00
move experimental/form_app to root of project (#623)
This allows us to reference this sample from other places. See https://github.com/flutter/flutter/pull/70321 for more context.
This commit is contained in:
214
form_app/lib/src/form_widgets.dart
Normal file
214
form_app/lib/src/form_widgets.dart
Normal file
@@ -0,0 +1,214 @@
|
||||
// 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);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user