在Android Studio中用Flutter实现FloatingActionButton添加卡片至列表
实现步骤与代码示例
1. 定义数据模型类
先创建存储卡片数据的模型类,方便后续数据传递与排序:
class CardItem { final String title; final DateTime date; final TimeOfDay time; CardItem({ required this.title, required this.date, required this.time, }); // 拼接日期与时间为完整DateTime,用于排序 DateTime get fullDateTime => DateTime( date.year, date.month, date.day, time.hour, time.minute, ); }
2. 实现独立卡片组件
创建你提到的独立卡片类(比如CustomCard.dart),接收CardItem数据渲染UI:
import 'package:flutter/material.dart'; import '../models/card_item.dart'; class CustomCard extends StatelessWidget { final CardItem item; const CustomCard({super.key, required this.item}); @override Widget build(BuildContext context) { return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item.title, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Text( "${item.date.year}/${item.date.month}/${item.date.day}", style: const TextStyle(color: Colors.grey), ), Text( "${item.time.hour.toString().padLeft(2, '0')}:${item.time.minute.toString().padLeft(2, '0')}", style: const TextStyle(color: Colors.grey), ), ], ), ), ); } }
3. 主页实现:跳转输入页+展示排序后的卡片
主页中添加按钮跳转输入页,接收返回数据后更新列表并按时间排序:
import 'package:flutter/material.dart'; import './input_form.dart'; import './models/card_item.dart'; import './widgets/custom_card.dart'; class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { final List<CardItem> _cardItems = []; // 跳转输入页并接收返回数据 void _navigateToInputForm() async { final newItem = await Navigator.push<CardItem>( context, MaterialPageRoute(builder: (context) => const InputFormPage()), ); if (newItem != null) { setState(() { _cardItems.add(newItem); // 按时间升序排序,如需最新在前则改为b.fullDateTime.compareTo(a.fullDateTime) _cardItems.sort((a, b) => a.fullDateTime.compareTo(b.fullDateTime)); }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('卡片列表')), body: _cardItems.isEmpty ? const Center(child: Text('暂无卡片,点击右下角添加')) : ListView.builder( itemCount: _cardItems.length, itemBuilder: (context, index) => CustomCard(item: _cardItems[index]), ), floatingActionButton: FloatingActionButton( onPressed: _navigateToInputForm, child: const Icon(Icons.add), ), ); } }
4. 输入表单页(input_form.dart)实现
完成输入表单,收集用户输入的标题、日期、时间,点击确认后返回数据给主页:
import 'package:flutter/material.dart'; import './models/card_item.dart'; class InputFormPage extends StatefulWidget { const InputFormPage({super.key}); @override State<InputFormPage> createState() => _InputFormPageState(); } class _InputFormPageState extends State<InputFormPage> { final _titleController = TextEditingController(); DateTime? _selectedDate; TimeOfDay? _selectedTime; // 选择日期 Future<void> _pickDate() async { final pickedDate = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2000), lastDate: DateTime(2100), ); if (pickedDate != null) { setState(() => _selectedDate = pickedDate); } } // 选择时间 Future<void> _pickTime() async { final pickedTime = await showTimePicker( context: context, initialTime: TimeOfDay.now(), ); if (pickedTime != null) { setState(() => _selectedTime = pickedTime); } } // 提交表单并返回数据 void _submitForm() { final title = _titleController.text.trim(); if (title.isEmpty || _selectedDate == null || _selectedTime == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('请填写完整信息')), ); return; } final newItem = CardItem( title: title, date: _selectedDate!, time: _selectedTime!, ); Navigator.pop(context, newItem); } @override void dispose() { _titleController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('创建新卡片')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( controller: _titleController, decoration: const InputDecoration(labelText: '标题'), ), const SizedBox(height: 16), ElevatedButton( onPressed: _pickDate, child: Text(_selectedDate != null ? "${_selectedDate!.year}/${_selectedDate!.month}/${_selectedDate!.day}" : '选择日期'), ), const SizedBox(height: 16), ElevatedButton( onPressed: _pickTime, child: Text(_selectedTime != null ? "${_selectedTime!.hour.toString().padLeft(2, '0')}:${_selectedTime!.minute.toString().padLeft(2, '0')}" : '选择时间'), ), const SizedBox(height: 32), ElevatedButton( onPressed: _submitForm, style: ElevatedButton.styleFrom(minimumSize: const Size(double.infinity, 50)), child: const Text('确认创建'), ), ], ), ), ); } }
关键逻辑说明
- 页面跳转与数据传递:通过
Navigator.push跳转输入页,用async/await接收返回的CardItem数据,非空则添加到列表。 - 排序逻辑:利用
CardItem的fullDateTime属性,将日期和时间组合为完整DateTime对象,调用sort方法实现时间排序。 - 表单校验:提交前检查必填项,避免空数据进入列表。
内容的提问来源于stack exchange,提问作者Mutant52
相关产品推荐
相关产品推荐

