You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter笔记应用:实现编辑页向列表页传递并展示数据

解决Flutter Firebase笔记应用的数据传递与展示问题

问题说明

当前笔记编辑页(Note)已通过onChanged绑定标题(zag)和内容(vm),并能保存到Firestore,但首页(Home)无法正确展示保存的笔记,且删除功能仅操作本地列表未同步到数据库。


修复步骤

1. 优化笔记编辑页(Note)

保存笔记后自动返回首页,并添加保存成功提示,提升用户体验:

// 修改"Зберегти нотатку"按钮的onPressed逻辑
TextButton(onPressed: () async {
  // 保存数据到Firestore
  await FirebaseFirestore.instance.collection('items').add({'zag': zag, 'vm': vm});
  
  if (mounted) {
    // 返回首页
    Navigator.of(context).pop();
    // 显示保存成功提示
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('笔记已保存')),
    );
  }
}, child: Text('Зберегти нотатку', style: GoogleFonts.montserrat(
  textStyle: const TextStyle(fontSize: 15, color: Colors.black, fontWeight: FontWeight.w600)
))),

2. 修复首页(Home)数据展示与删除逻辑

首页已使用StreamBuilder监听Firestore数据,但未正确利用快照数据,需修改以下几点:

  • 移除无用的本地变量(notes、zag、vm等)
  • 基于Firestore快照渲染笔记列表
  • 删除操作直接同步到Firestore数据库

修改后的首页核心代码:

class _HomeState extends State<Home> {
  void initFireBase() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Firebase.initializeApp();
  }

  @override
  void initState(){
    super.initState();
    initFireBase();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: FirebaseFirestore.instance.collection('items').snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        // 加载状态处理
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }
        // 无数据状态处理
        if (!snapshot.hasData || snapshot.data!.docs.isEmpty) {
          return const Scaffold(
            body: SafeArea(
              child: Center(child: Text('Нема записів')),
            ),
          );
        }

        return Scaffold(
          floatingActionButton: Padding(
            padding: const EdgeInsets.only(bottom: 35.0),
            child: Align(
              alignment: FractionalOffset.bottomCenter,
              child: SizedBox(
                width: 68,
                height: 68,
                child: FloatingActionButton(
                  elevation: 0,
                  backgroundColor: const Color.fromARGB(255, 57, 26, 26),
                  onPressed: (){
                    Navigator.push(context, MaterialPageRoute(builder: (context) => const Note()));
                  },
                  child: const Icon(Icons.add, size: 66,),
                ),
              ),
            ),
          ),
          resizeToAvoidBottomInset: false,
          backgroundColor: Colors.white,
          appBar: null,
          body: SafeArea(
            child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.only(top: 55,right: 252),
                  child: Text('Notely', 
                    style: GoogleFonts.montserrat(textStyle: const TextStyle(fontSize: 28,fontWeight: FontWeight.w700, color: Colors.black),)),
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 12, left: 20, right: 20),
                  child: SizedBox(
                    height: 50.0,
                    width: 365,
                    child: TextField(
                      decoration: InputDecoration(
                        filled: true,
                        fillColor: const Color.fromARGB(255, 217, 217, 217),
                        border: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(16.0),
                          borderSide: BorderSide.none
                        ),
                        hintText: 'Пошук', 
                        hintStyle: GoogleFonts.montserrat(textStyle: const TextStyle(fontSize: 13.8, fontWeight: FontWeight.w500, color: Colors.black),),
                        contentPadding: const EdgeInsets.only(left: 16),
                      ),
                    ),
                  ),
                ),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.only(top: 15),
                    child: ListView.builder(
                      itemCount: snapshot.data!.docs.length,
                      itemBuilder: (BuildContext context, int index) {
                        // 获取当前笔记的文档和数据
                        final noteDoc = snapshot.data!.docs[index];
                        final noteData = noteDoc.data() as Map<String, dynamic>;
                        final title = noteData['zag'] ?? '无标题';
                        final content = noteData['vm'] ?? '无内容';

                        return ListTile(
                          title: Text(title, style: GoogleFonts.montserrat(textStyle: const TextStyle(fontWeight: FontWeight.w700))),
                          subtitle: Text(content, style: GoogleFonts.montserrat(textStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500))),
                          onLongPress: () {
                            showDialog(
                              context: context,
                              builder: (BuildContext context) {
                                return AlertDialog(
                                  title: const Text('Видалити елемент?'),
                                  content: const Text('Ви впевнені, що хочете видалити цей елемент?'),
                                  actions: <Widget>[
                                    TextButton(
                                      child: const Text('Ні'),
                                      onPressed: () => Navigator.of(context).pop(),
                                    ),
                                    TextButton(
                                      child: const Text('Так'),
                                      onPressed: () async {
                                        // 从Firestore删除文档
                                        await noteDoc.reference.delete();
                                        Navigator.of(context).pop();
                                        if (mounted) {
                                          ScaffoldMessenger.of(context).showSnackBar(
                                            const SnackBar(content: Text('笔记已删除')),
                                          );
                                        }
                                      },
                                    ),
                                  ],
                                );
                              },
                            );
                          },
                        );
                      },
                    ),
                  ),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

关键改进点

  • 数据流向:编辑页→Firestore→首页(通过StreamBuilder实时监听),实现数据同步
  • 状态处理:添加加载状态、空数据状态的UI反馈
  • 用户体验:保存/删除后添加提示,并自动返回首页
  • 数据安全:删除操作直接操作Firestore,确保数据一致性

内容的提问来源于stack exchange,提问作者Назар Марцинко

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:47:35