Flutter User Input
This section will introduce how to handle user input in Flutter applications, including text input, button clicks, form handling, and more.
TextField - Text Input
TextField is the most commonly used text input widget in Flutter.
Example: TextField Basic Usage
// The simplest TextField
TextField()
// TextField with decoration
TextField(
decoration: const InputDecoration(
labelText: Username, // Label
hintText: 'Please enter username', // Hint text
prefixIcon: Icon(Icons.person), // Prefix icon
),
)
// TextField with border
TextField(
decoration: InputDecoration(
border: OutlineInputBorder( // Outer border
borderRadius: BorderRadius.circular(8),
),
labelText: Password,
),
obscureText: true, // Hide input content (password scenario)
)
// Multi-line text input
TextField(
maxLines: 3, // Maximum lines
decoration: const InputDecoration(
hintText: 'Please enter multi-line text',
),
)
TextField()
// TextField with decoration
TextField(
decoration: const InputDecoration(
labelText: Username, // Label
hintText: 'Please enter username', // Hint text
prefixIcon: Icon(Icons.person), // Prefix icon
),
)
// TextField with border
TextField(
decoration: InputDecoration(
border: OutlineInputBorder( // Outer border
borderRadius: BorderRadius.circular(8),
),
labelText: Password,
),
obscureText: true, // Hide input content (password scenario)
)
// Multi-line text input
TextField(
maxLines: 3, // Maximum lines
decoration: const InputDecoration(
hintText: 'Please enter multi-line text',
),
)
TextEditingController - Text Controller
Using TextEditingController, you can read and control the content of TextField.
< h2 class="example">Example: TextEditingController usage
class TextFieldExample extends StatefulWidget {
const TextFieldExample({super.key});
@override
State<TextFieldExample> createState() => _TextFieldExampleState();
}
class _TextFieldExampleState extends State<TextFieldExample> {
// Create controller
final TextEditingController _controller = TextEditingController();
String _displayText = '';
@override
void dispose() {
// Dispose controller
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: _controller, // Bind controller
decoration: const InputDecoration(
labelText: 'Enter text',
),
onChanged: (text) {
// Listen for text changes
print('Current input: $text');
},
),
const SizedBox(height: 20),
// Display input text
Text('You entered: $_displayText'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Read text
setState(() {
_displayText = _controller.text;
});
},
child: const Text('Show input'),
),
ElevatedButton(
onPressed: () {
// Clear text
_controller.clear();
},
child: const Text('Clear'),
),
ElevatedButton(
onPressed: () {
// Set text
_controller.text = 'Preset text';
},
child: const Text('Set text'),
),
],
);
}
}
const TextFieldExample({super.key});
@override
State<TextFieldExample> createState() => _TextFieldExampleState();
}
class _TextFieldExampleState extends State<TextFieldExample> {
// Create controller
final TextEditingController _controller = TextEditingController();
String _displayText = '';
@override
void dispose() {
// Dispose controller
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
controller: _controller, // Bind controller
decoration: const InputDecoration(
labelText: 'Enter text',
),
onChanged: (text) {
// Listen for text changes
print('Current input: $text');
},
),
const SizedBox(height: 20),
// Display input text
Text('You entered: $_displayText'),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Read text
setState(() {
_displayText = _controller.text;
});
},
child: const Text('Show input'),
),
ElevatedButton(
onPressed: () {
// Clear text
_controller.clear();
},
child: const Text('Clear'),
),
ElevatedButton(
onPressed: () {
// Set text
_controller.text = 'Preset text';
},
child: const Text('Set text'),
),
],
);
}
}
Focus control
Using FocusNode allows you to control the focus of input fields.
Example: Focus Control
class FocusExample extends StatefulWidget {
const FocusExample({super.key});
@override
State<FocusExample> createState() => _FocusExampleState();
}
class _FocusExampleState extends State<FocusExample> {
final FocusNode _focusNode1 = FocusNode();
final FocusNode _focusNode2 = FocusNode();
@override
void dispose() {
_focusNode1.dispose();
_focusNode2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
focusNode: _focusNode1,
decoration: const InputDecoration(labelText: 'Input field 1'),
),
const SizedBox(height: 10),
TextField(
focusNode: _focusNode2,
decoration: const InputDecoration(labelText: 'Input field 2'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Focus on input field 1
_focusNode1.requestFocus();
},
child: const Text('Focus input field 1'),
),
ElevatedButton(
onPressed: () {
// Focus on input field 2
_focusNode2.requestFocus();
},
child: const Text('Focus input field 2'),
),
ElevatedButton(
onPressed: () {
// Remove focus
_focusNode1.unfocus();
_focusNode2.unfocus();
},
child: const Text('Remove focus'),
),
],
);
}
}
const FocusExample({super.key});
@override
State<FocusExample> createState() => _FocusExampleState();
}
class _FocusExampleState extends State<FocusExample> {
final FocusNode _focusNode1 = FocusNode();
final FocusNode _focusNode2 = FocusNode();
@override
void dispose() {
_focusNode1.dispose();
_focusNode2.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
TextField(
focusNode: _focusNode1,
decoration: const InputDecoration(labelText: 'Input field 1'),
),
const SizedBox(height: 10),
TextField(
focusNode: _focusNode2,
decoration: const InputDecoration(labelText: 'Input field 2'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Focus on input field 1
_focusNode1.requestFocus();
},
child: const Text('Focus input field 1'),
),
ElevatedButton(
onPressed: () {
// Focus on input field 2
_focusNode2.requestFocus();
},
child: const Text('Focus input field 2'),
),
ElevatedButton(
onPressed: () {
// Remove focus
_focusNode1.unfocus();
_focusNode2.unfocus();
},
child: const Text('Remove focus'),
),
],
);
}
}
Buttons and Click Events
Flutter provides a variety of button components for handling user clicks.
Example: Various Buttons
// TextButton - text button
TextButton(
onPressed: () => print('Clicked the text button'),
child: const Text('Text button'),
)
// ElevatedButton - raised button
ElevatedButton(
onPressed: () => print('Clicked the raised button'),
child: const Text('Submit'),
)
// OutlinedButton - outlined button
OutlinedButton(
onPressed: () => print('Clicked the outlined button'),
child: const Text('Cancel'),
)
// IconButton - icon button
IconButton(
icon: const Icon(Icons.favorite),
onPressed: () => print('Clicked the icon button'),
)
// Button with icon
ElevatedButton.icon(
onPressed: () => print('Clicked the button with icon'),
icon: const Icon(Icons.save),
label: const Text('Save'),
)
// CupertinoButton - iOS-style button
CupertinoButton(
child: const Text('iOS button'),
onPressed: () {},
)
TextButton(
onPressed: () => print('Clicked the text button'),
child: const Text('Text button'),
)
// ElevatedButton - raised button
ElevatedButton(
onPressed: () => print('Clicked the raised button'),
child: const Text('Submit'),
)
// OutlinedButton - outlined button
OutlinedButton(
onPressed: () => print('Clicked the outlined button'),
child: const Text('Cancel'),
)
// IconButton - icon button
IconButton(
icon: const Icon(Icons.favorite),
onPressed: () => print('Clicked the icon button'),
)
// Button with icon
ElevatedButton.icon(
onPressed: () => print('Clicked the button with icon'),
icon: const Icon(Icons.save),
label: const Text('Save'),
)
// CupertinoButton - iOS-style button
CupertinoButton(
child: const Text('iOS button'),
onPressed: () {},
)
Switch、Checkbox、Radio
Example: Switch, Checkbox, Radio Button
class SwitchCheckboxExample extends StatefulWidget {
const SwitchCheckboxExample({super.key});
@override
State<SwitchCheckboxExample> createState() => _SwitchCheckboxExampleState();
}
class _SwitchCheckboxExampleState extends State<SwitchCheckboxExample> {
bool _switchValue = false;
bool _checkboxValue = false;
String _radioValue = 'A';
@override
Widget build(BuildContext context) {
return Column(
children: [
// Switch - toggle
Switch(
value: _switchValue,
onChanged: (value) {
setState(() {
_switchValue = value;
});
},
),
Text('Switch value: $_switchValue'),
// Checkbox - check box
Checkbox(
value: _checkboxValue,
onChanged: (value) {
setState(() {
_checkboxValue = value ?? false;
});
},
),
Text('Checkbox value: $_checkboxValue'),
// Radio - radio button
Row(
children: [
Radio<String>(
value: 'A',
groupValue: _radioValue,
onChanged: (value) {
setState(() {
_radioValue = value!;
});
},
),
const Text('Option A'),
Radio<String>(
value: 'B',
groupValue: _radioValue,
onChanged: (value) {
setState(() {
_radioValue = value!;
});
},
),
const Text('Option B'),
],
),
Text('Radio value: $_radioValue'),
],
);
}
}
const SwitchCheckboxExample({super.key});
@override
State<SwitchCheckboxExample> createState() => _SwitchCheckboxExampleState();
}
class _SwitchCheckboxExampleState extends State<SwitchCheckboxExample> {
bool _switchValue = false;
bool _checkboxValue = false;
String _radioValue = 'A';
@override
Widget build(BuildContext context) {
return Column(
children: [
// Switch - toggle
Switch(
value: _switchValue,
onChanged: (value) {
setState(() {
_switchValue = value;
});
},
),
Text('Switch value: $_switchValue'),
// Checkbox - check box
Checkbox(
value: _checkboxValue,
onChanged: (value) {
setState(() {
_checkboxValue = value ?? false;
});
},
),
Text('Checkbox value: $_checkboxValue'),
// Radio - radio button
Row(
children: [
Radio<String>(
value: 'A',
groupValue: _radioValue,
onChanged: (value) {
setState(() {
_radioValue = value!;
});
},
),
const Text('Option A'),
Radio<String>(
value: 'B',
groupValue: _radioValue,
onChanged: (value) {
setState(() {
_radioValue = value!;
});
},
),
const Text('Option B'),
],
),
Text('Radio value: $_radioValue'),
],
);
}
}
Slider - Slider
Example: Slider Usage
class SliderExample extends StatefulWidget {
const SliderExample({super.key});
@override
State<SliderExample> createState() => _SliderExampleState();
}
class _SliderExampleState extends State<SliderExample> {
double _sliderValue = 0.5;
@override
Widget build(BuildContext context) {
return Column(
children: [
Slider(
value: _sliderValue, // Current value (0.0-1.0)
min: 0.0,
max: 1.0,
divisions: 10, // Divide into 10 ticks
label: '${(_sliderValue * 100).round()}%',
onChanged: (value) {
setState(() {
_sliderValue = value;
});
},
),
Text('Current value: ${(_sliderValue * 100).round()}%'),
// Range slider
RangeSlider(
values: const RangeValues(0.3, 0.7),
min: 0.0,
max: 1.0,
onChanged: (values) {
print('Range: ${values.start} - ${values.end}');
},
),
],
);
}
}
const SliderExample({super.key});
@override
State<SliderExample> createState() => _SliderExampleState();
}
class _SliderExampleState extends State<SliderExample> {
double _sliderValue = 0.5;
@override
Widget build(BuildContext context) {
return Column(
children: [
Slider(
value: _sliderValue, // Current value (0.0-1.0)
min: 0.0,
max: 1.0,
divisions: 10, // Divide into 10 ticks
label: '${(_sliderValue * 100).round()}%',
onChanged: (value) {
setState(() {
_sliderValue = value;
});
},
),
Text('Current value: ${(_sliderValue * 100).round()}%'),
// Range slider
RangeSlider(
values: const RangeValues(0.3, 0.7),
min: 0.0,
max: 1.0,
onChanged: (values) {
print('Range: ${values.start} - ${values.end}');
},
),
],
);
}
}
other extensionsWhen handling user input, remember to use setState to update the UI state so that the interface can respond to user actions.