Commit 7d346dd1 authored by Matt Perry's avatar Matt Perry Committed by GitHub

Improve docs for Input and Form and friends. (#7208)

Fixes https://github.com/flutter/flutter/issues/7017
parent 5a864ded
......@@ -18,7 +18,10 @@ export 'package:flutter/services.dart' show TextInputType;
const Duration _kTransitionDuration = const Duration(milliseconds: 200);
const Curve _kTransitionCurve = Curves.fastOutSlowIn;
/// A simple text input field.
/// A simple undecorated text input field.
///
/// If you want decorations as specified in the Material spec (most likely),
/// use [Input] instead.
///
/// This widget is comparable to [Text] in that it does not include a margin
/// or any decoration outside the text itself. It is useful for applications,
......@@ -35,6 +38,7 @@ const Curve _kTransitionCurve = Curves.fastOutSlowIn;
///
/// * [Input], which adds a label, a divider below the text field, and support for
/// an error message.
/// * [RawInput], a text field that does not require [Material] design.
class InputField extends StatefulWidget {
InputField({
Key key,
......@@ -143,7 +147,6 @@ class _InputFieldState extends State<InputField> {
];
if (config.hintText != null && value.text.isEmpty) {
TextStyle hintStyle = textStyle.copyWith(color: themeData.hintColor);
stackChildren.add(
new Positioned(
......@@ -373,13 +376,23 @@ class _InputContainerState extends State<InputContainer> {
///
/// Requires one of its ancestors to be a [Material] widget.
///
/// See also:
/// When using inside a [Form], consider using [InputFormField] instead.
///
/// * <https://material.google.com/components/text-fields.html>
/// Assuming that the input is already focused, the basic data flow for
/// retrieving user input is:
/// 1. User taps a character on the keyboard.
/// 2. The [onChanged] callback is called with the current [InputValue].
/// 3. Perform any necessary logic/validation on the current input value.
/// 4. Update the state of the [Input] widget accordingly through [State.setState].
///
/// For a detailed guide on using the input widget, see:
/// For most cases, we recommend that you use the [Input] class within a
/// [StatefulWidget] so you can save and operate on the current value of the
/// input.
///
/// * <https://flutter.io/text-input/>
/// See also:
///
/// * <https://material.google.com/components/text-fields.html>
/// * [InputFormField], which simplifies steps 2-4 above.
class Input extends StatefulWidget {
/// Creates a text input field.
///
......@@ -520,6 +533,76 @@ class _InputState extends State<Input> {
}
/// A [FormField] that contains an [Input].
///
/// This is a convenience widget that simply wraps an [Input] widget in a
/// [FormField]. The [FormField] maintains the current value of the [Input] so
/// that you don't need to manage it yourself.
///
/// A [Form] ancestor is not required. The [Form] simply makes it easier to
/// save, reset, or validate multiple fields at once. To use without a [Form],
/// pass a [GlobalKey] to the constructor and use [GlobalKey.currentState] to
/// save or reset the form field.
///
/// To see the use of [InputFormField], compare these two ways of a implementing
/// a simple two text field form.
///
/// Using [InputFormField]:
///
/// ```dart
/// String _firstName, _lastName;
/// GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
/// ...
/// new Form(
/// key: _formKey,
/// child: new Row(
/// children: <Widget>[
/// new InputFormField(
/// labelText: 'First Name',
/// onSaved: (InputValue value) { _firstName = value.text; }
/// ),
/// new InputFormField(
/// labelText: 'Last Name',
/// onSaved: (InputValue value) { _lastName = value.text; }
/// ),
/// new RaisedButton(
/// child: new Text('SUBMIT'),
/// // Instead of _formKey.currentState, you could wrap the
/// // RaisedButton in a Builder widget to get access to a BuildContext,
/// // and use Form.of(context).
/// onPressed: () { _formKey.currentState.save(); },
/// ),
/// )
/// )
/// ```
///
/// Using [Input] directly:
///
/// ```dart
/// String _firstName, _lastName;
/// InputValue _firstNameValue = const InputValue();
/// InputValue _lastNameValue = const InputValue();
/// ...
/// new Row(
/// children: <Widget>[
/// new Input(
/// value: _firstNameValue,
/// labelText: 'First Name',
/// onChanged: (InputValue value) { setState( () { _firstNameValue = value; } ); }
/// ),
/// new Input(
/// value: _lastNameValue,
/// labelText: 'Last Name',
/// onChanged: (InputValue value) { setState( () { _lastNameValue = value; } ); }
/// ),
/// new RaisedButton(
/// child: new Text('SUBMIT'),
/// onPressed: () {
/// _firstName = _firstNameValue.text;
/// _lastName = _lastNameValue.text;
/// },
/// ),
/// )
/// ```
class InputFormField extends FormField<InputValue> {
InputFormField({
Key key,
......
......@@ -6,8 +6,15 @@ import 'package:flutter/foundation.dart';
import 'framework.dart';
/// A container for grouping together multiple form field widgets (e.g.
/// [Input] widgets).
/// An optional container for grouping together multiple form field widgets
/// (e.g. [Input] widgets).
///
/// Each individual form field should be wrapped in a [FormField] widget, with
/// the [Form] widget as a common ancestor of all of those. Call methods on
/// [FormState] to save, reset, or validate each [FormField] that is a
/// descendant of this [Form]. To obtain the [FormState], you may use [Form.of]
/// with a context whose ancestor is the [Form], or pass a [GlobalKey] to the
/// [Form] constructor and call [GlobalKey.currentState].
class Form extends StatefulWidget {
/// Creates a container for form fields.
///
......@@ -141,6 +148,11 @@ typedef Widget FormFieldBuilder<T>(FormFieldState<T> field);
/// Use a [GlobalKey] with [FormField] if you want to retrieve its current
/// state, for example if you want one form field to depend on another.
///
/// A [Form] ancestor is not required. The [Form] simply makes it easier to
/// save, reset, or validate multiple fields at once. To use without a [Form],
/// pass a [GlobalKey] to the constructor and use [GlobalKey.currentState] to
/// save or reset the form field.
///
/// See also: [Form], [InputFormField]
class FormField<T> extends StatefulWidget {
FormField({
......@@ -173,6 +185,8 @@ class FormField<T> extends StatefulWidget {
FormFieldState<T> createState() => new FormFieldState<T>();
}
/// The current state of a [FormField]. Passed to the [FormFieldBuilder] method
/// for use in constructing the form field's widget.
class FormFieldState<T> extends State<FormField<T>> {
T _value;
String _errorText;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment