Flutter学习之输入组件

Flutter 输入组件全面指南

Flutter 提供了丰富的输入组件,用于构建用户交互界面。这些组件遵循 Material Design 规范,同时提供了强大的自定义能力。下面我将详细介绍 Flutter 中的主要输入组件及其用法。

核心输入组件

1. TextField - 基础文本输入框

dart 复制代码
TextField(
decoration: InputDecoration(
labelText: '用户名',
hintText: '请输入您的用户名',
prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
filled: true,
fillColor: Colors.grey[100],
),
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
onChanged: (value) {
print('输入内容: $value');
},
onSubmitted: (value) {
print('提交内容: $value');
},
)

2. TextFormField - 表单文本输入框(带验证)

dart 复制代码
TextFormField(
controller: _emailController,
decoration: InputDecoration(
labelText: '邮箱',
hintText: 'example@domain.com',
prefixIcon: Icon(Icons.email),
border: OutlineInputBorder(),
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入邮箱地址';
}
if (!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) {
return '邮箱格式不正确';
}
return null;
},
)

选择器组件

3. Checkbox - 复选框

dart 复制代码
bool _isChecked = false;

Checkbox(
value: _isChecked,
onChanged: (bool? value) {
setState(() {
_isChecked = value!;
});
},
)

4. CheckboxListTile - 带标签的复选框

dart 复制代码
bool _isChecked = false;

CheckboxListTile(
title: Text('同意用户协议'),
subtitle: Text('请仔细阅读用户协议'),
value: _isChecked,
onChanged: (bool? value) {
setState(() {
_isChecked = value!;
});
},
secondary: Icon(Icons.description),
)

5. Switch - 开关

dart 复制代码
bool _isSwitched = false;

Switch(
value: _isSwitched,
onChanged: (bool value) {
setState(() {
_isSwitched = value;
});
},
)

6. Radio - 单选按钮

dart 复制代码
enum Gender { male, female }
Gender? _selectedGender = Gender.male;

Column(
children: [
RadioListTile<Gender>(
title: Text('男性'),
value: Gender.male,
groupValue: _selectedGender,
onChanged: (Gender? value) {
setState(() {
_selectedGender = value;
});
},
),
RadioListTile<Gender>(
title: Text('女性'),
value: Gender.female,
groupValue: _selectedGender,
onChanged: (Gender? value) {
setState(() {
_selectedGender = value;
});
},
),
],
)

7. Slider - 滑块

dart 复制代码
double _sliderValue = 50;

Slider(
value: _sliderValue,
min: 0,
max: 100,
divisions: 10,
label: _sliderValue.round().toString(),
onChanged: (double value) {
setState(() {
_sliderValue = value;
});
},
)

8. RangeSlider - 范围滑块

dart 复制代码
RangeValues _currentRangeValues = RangeValues(20, 80);

RangeSlider(
values: _currentRangeValues,
min: 0,
max: 100,
divisions: 10,
labels: RangeLabels(
_currentRangeValues.start.round().toString(),
_currentRangeValues.end.round().toString(),
),
onChanged: (RangeValues values) {
setState(() {
_currentRangeValues = values;
});
},
)
dart 复制代码
String? _selectedItem = '选项1';
List<String> _items = ['选项1', '选项2', '选项3'];

DropdownButton<String>(
value: _selectedItem,
items: _items.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
_selectedItem = newValue;
});
},
)

日期和时间选择器

10. showDatePicker - 日期选择器

dart 复制代码
DateTime? _selectedDate;

ElevatedButton(
onPressed: () async {
final DateTime? picked = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2000),
lastDate: DateTime(2100),
builder: (context, child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light(
primary: Colors.blue,
onPrimary: Colors.white,
),
),
child: child!,
);
},
);
if (picked != null && picked != _selectedDate) {
setState(() {
_selectedDate = picked;
});
}
},
child: Text('选择日期'),
)

11. showTimePicker - 时间选择器

dart 复制代码
TimeOfDay? _selectedTime;

ElevatedButton(
onPressed: () async {
final TimeOfDay? picked = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
builder: (context, child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light(
primary: Colors.blue,
onPrimary: Colors.white,
),
),
child: child!,
);
},
);
if (picked != null && picked != _selectedTime) {
setState(() {
_selectedTime = picked;
});
}
},
child: Text('选择时间'),
)

表单处理

12. Form 和 GlobalKey

dart 复制代码
final _formKey = GlobalKey<FormState>();
TextEditingController _nameController = TextEditingController();
TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();

Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _nameController,
decoration: InputDecoration(labelText: '姓名'),
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入姓名';
}
return null;
},
),
TextFormField(
controller: _emailController,
decoration: InputDecoration(labelText: '邮箱'),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入邮箱';
}
if (!value.contains('@')) {
return '邮箱格式不正确';
}
return null;
},
),
TextFormField(
controller: _passwordController,
decoration: InputDecoration(labelText: '密码'),
obscureText: true,
validator: (value) {
if (value == null || value.length < 6) {
return '密码长度至少6位';
}
return null;
},
),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
// 表单验证通过
print('姓名: ${_nameController.text}');
print('邮箱: ${_emailController.text}');
print('密码: ${_passwordController.text}');
}
},
child: Text('提交'),
),
],
),
)

高级输入组件

13. Autocomplete - 自动完成

dart 复制代码
final List<String> _options = [
'Apple',
'Banana',
'Cherry',
'Date',
'Fig',
'Grape',
'Lemon',
'Mango',
'Orange',
'Peach',
'Pear',
'Pineapple',
'Strawberry',
];

Autocomplete<String>(
optionsBuilder: (TextEditingValue textEditingValue) {
if (textEditingValue.text == '') {
return const Iterable<String>.empty();
}
return _options.where((String option) {
return option.toLowerCase().contains(textEditingValue.text.toLowerCase());
});
},
onSelected: (String selection) {
print('选择了: $selection');
},
)
dart 复制代码
SearchBar(
hintText: '搜索...',
leading: Icon(Icons.search),
trailing: [
IconButton(
icon: Icon(Icons.filter_list),
onPressed: () {
print('打开筛选器');
},
),
],
onChanged: (value) {
print('搜索内容: $value');
},
onSubmitted: (value) {
print('提交搜索: $value');
},
)

自定义输入组件

15. 自定义表单字段

dart 复制代码
class CustomInputField extends StatelessWidget {
final String label;
final IconData? icon;
final bool obscureText;
final TextEditingController? controller;
final String? Function(String?)? validator;

const CustomInputField({
required this.label,
this.icon,
this.obscureText = false,
this.controller,
this.validator,
});

@override
Widget build(BuildContext context) {
return TextFormField(
controller: controller,
obscureText: obscureText,
decoration: InputDecoration(
labelText: label,
prefixIcon: icon != null ? Icon(icon) : null,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
filled: true,
fillColor: Colors.grey[100],
),
validator: validator,
);
}
}

// 使用示例
CustomInputField(
label: '密码',
icon: Icons.lock,
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty) {
return '密码不能为空';
}
return null;
},
)

最佳实践

  1. 表单验证:始终验证用户输入,提供清晰的错误信息
  2. 键盘类型 :根据输入内容选择合适的键盘类型(keyboardType
  3. 无障碍性:确保所有输入组件都有适当的标签和语义
  4. 状态管理:使用控制器管理文本输入状态
  5. 输入格式 :使用 inputFormatters 限制输入格式
  6. 错误处理:优雅地处理验证错误
  7. 焦点管理 :使用 FocusNode 管理输入焦点
dart 复制代码
// 焦点管理示例
FocusNode _emailFocus = FocusNode();
FocusNode _passwordFocus = FocusNode();

TextFormField(
focusNode: _emailFocus,
decoration: InputDecoration(labelText: '邮箱'),
textInputAction: TextInputAction.next,
onFieldSubmitted: (value) {
FocusScope.of(context).requestFocus(_passwordFocus);
},
)

总结

Flutter 提供了丰富的输入组件,从基本的文本输入到复杂的日期选择器,满足各种用户输入需求。关键组件包括:

  • TextField/TextFormField:用于文本输入
  • 选择器:Checkbox, Switch, Radio, Slider, DropdownButton
  • 日期/时间选择器:showDatePicker, showTimePicker
  • 表单处理:Form, GlobalKey, 验证逻辑
  • 高级组件:Autocomplete, SearchBar

通过组合这些组件并遵循最佳实践,您可以创建直观、高效且用户友好的输入界面。

相关推荐
吃不胖爹2 小时前
Flutter 基本架构与使用
javascript·flutter·架构
Genios2 小时前
今天是我正式开启Python学习之旅的第7天
开发语言·python·学习
倔强的胖蚂蚁2 小时前
基于云原生的 VMware NAT 网络端口映射
网络·学习·云原生
星幻元宇VR2 小时前
VR自行车|开启沉浸式交通安全新体验
科技·学习·安全·vr·虚拟现实
鱼鳞_2 小时前
Java学习笔记_Day19
java·笔记·学习
浮游本尊2 小时前
React 18.x 学习计划 - 第十五天:GraphQL 与实时应用实战
学习·react.js·graphql
禹中一只鱼13 小时前
【力扣热题100学习笔记】 - 哈希
java·学习·leetcode·哈希算法
SteveSenna14 小时前
项目:Trossen Arm MuJoCo
人工智能·学习·算法
m0_7473041614 小时前
GNN学习
学习