初学者求教:Flutter是否有类似Bootstrap的开源预构建组件库?
类似Bootstrap的Flutter开源UI组件库
当然有不少对标Bootstrap的预构建Widget库,能帮你快速搭建UI,不用从零开发:
- Flutter Bootstrap:完全遵循Bootstrap设计规范,提供栅格系统、按钮、表单、卡片等常用组件,用法和Web端Bootstrap高度相似,适合有Web开发经验的开发者快速上手。
- Material Design Components (MDC) for Flutter:官方维护的Material风格组件库,虽然不是Bootstrap样式,但提供了大量开箱即用的组件(比如输入框、按钮、对话框),稳定性和兼容性拉满,是Flutter开发的标配。
- Cupertino Widgets:官方的iOS风格组件库,如果你需要开发iOS原生风格的APP,这个库的所有组件都是预构建好的,直接调用即可。
- FlutterFlow UI Kit:包含大量现成的UI组件,覆盖从基础元素到复杂布局的场景,适合快速搭建原型或直接用于生产项目。
表单、表格场景的预构建代码示例
基础表单示例
下面是一个包含输入验证、单选框、复选框的完整表单,基于Material组件实现:
import 'package:flutter/material.dart'; class UserForm extends StatefulWidget { const UserForm({super.key}); @override State<UserForm> createState() => _UserFormState(); } class _UserFormState extends State<UserForm> { final _formKey = GlobalKey<FormState>(); String? _username; String? _email; bool _agreeTerms = false; String? _gender; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('用户注册')), body: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( decoration: const InputDecoration(labelText: '用户名'), validator: (value) { if (value == null || value.isEmpty) { return '请输入用户名'; } return null; }, onSaved: (value) => _username = value, ), TextFormField( decoration: const InputDecoration(labelText: '邮箱'), keyboardType: TextInputType.emailAddress, validator: (value) { if (value == null || !RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value)) { return '请输入有效的邮箱地址'; } return null; }, onSaved: (value) => _email = value, ), const SizedBox(height: 16), const Text('性别'), Row( children: [ Radio( value: 'male', groupValue: _gender, onChanged: (value) => setState(() => _gender = value), ), const Text('男'), Radio( value: 'female', groupValue: _gender, onChanged: (value) => setState(() => _gender = value), ), const Text('女'), ], ), CheckboxListTile( title: const Text('同意服务条款与隐私政策'), value: _agreeTerms, onChanged: (value) => setState(() => _agreeTerms = value!), validator: (value) { if (value == false) { return '必须同意条款才能继续'; } return null; }, ), const SizedBox(height: 24), ElevatedButton( onPressed: () { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); // 处理表单提交逻辑,比如发送到服务器 print('用户名: $_username, 邮箱: $_email, 性别: $_gender'); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('注册成功!')), ); } }, child: const Text('注册'), ), ], ), ), ), ); } }
基础表格示例
下面是支持排序功能的DataTable实现,适合展示结构化数据:
import 'package:flutter/material.dart'; class EmployeeTable extends StatefulWidget { const EmployeeTable({super.key}); @override State<EmployeeTable> createState() => _EmployeeTableState(); } class _EmployeeTableState extends State<EmployeeTable> { final List<Map<String, dynamic>> _employees = [ {'id': 1, 'name': '张三', 'age': 25, 'department': '前端开发'}, {'id': 2, 'name': '李四', 'age': 30, 'department': '后端开发'}, {'id': 3, 'name': '王五', 'age': 28, 'department': 'UI设计'}, {'id': 4, 'name': '赵六', 'age': 32, 'department': '产品经理'}, ]; int _sortColumnIndex = 0; bool _sortAscending = true; void _sort<T>(Comparable<T> Function(Map<String, dynamic> emp) getField, int columnIndex) { if (_sortColumnIndex == columnIndex) { setState(() => _sortAscending = !_sortAscending); } else { setState(() { _sortColumnIndex = columnIndex; _sortAscending = true; }); } _employees.sort((a, b) { final aValue = getField(a); final bValue = getField(b); return _sortAscending ? aValue.compareTo(bValue) : bValue.compareTo(aValue); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('员工信息表')), body: Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( sortColumnIndex: _sortColumnIndex, sortAscending: _sortAscending, columns: [ DataColumn( label: const Text('ID'), onSort: (columnIndex, ascending) => _sort((emp) => emp['id'] as int, columnIndex), ), DataColumn( label: const Text('姓名'), onSort: (columnIndex, ascending) => _sort((emp) => emp['name'] as String, columnIndex), ), DataColumn( label: const Text('年龄'), onSort: (columnIndex, ascending) => _sort((emp) => emp['age'] as int, columnIndex), ), DataColumn( label: const Text('部门'), onSort: (columnIndex, ascending) => _sort((emp) => emp['department'] as String, columnIndex), ), ], rows: _employees.map((emp) { return DataRow( cells: [ DataCell(Text(emp['id'].toString())), DataCell(Text(emp['name'])), DataCell(Text(emp['age'].toString())), DataCell(Text(emp['department'])), ], ); }).toList(), ), ), ), ); } }
内容的提问来源于stack exchange,提问作者ABHISHEK REDDY GOTHAM
相关产品推荐
相关产品推荐

