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

Flutter中Set<String>从Future获取后无法在界面显示问题求助

Flutter问题:从SharedPreferences获取数据后无法展示Card组件

我看了你的代码和日志,能确认你已经成功从SharedPreferences拿到了数据,但界面上看不到Card,大概率是这两个原因:

  • 你的Scaffold没有设置AppBar,导致生成的Card被顶部的状态栏遮挡住了,看起来像是没显示;
  • 每次添加Card都调用一次setState(),虽然功能没问题,但会多次触发界面重建,效率很低。

下面是修改后的代码,我调整了这两个点,同时优化了数据处理的逻辑:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SavedForms extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SavedForms();
}

class _SavedForms extends State<SavedForms>{
  List<Card> myForms = [];

  @override
  void initState(){
    super.initState(); // 先调用super.initState再执行自定义逻辑,符合Flutter生命周期规范
    getKeys();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Saved Forms")), // 添加AppBar避免内容被状态栏遮挡
      body: Column(
        children: <Widget>[
          ...myForms,
          // 无数据时显示提示,避免界面空白
          if(myForms.isEmpty) const Padding(
            padding: EdgeInsets.all(16.0),
            child: Text("暂无保存的表单"),
          )
        ],
      ),
    );
  }

  void getKeys() async {
    // 改用async/await写法,比链式then更易读维护
    final result = await getData();
    // 一次性创建所有Card后再统一更新状态,减少界面重建次数
    final newCards = result.map((element) {
      print("displaying ${element.toString()}");
      return Card(
        margin: const EdgeInsets.all(8.0), // 给Card加外边距,视觉效果更舒适
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Text(element.toString()),
        ),
      );
    }).toList();
    
    setState(() {
      myForms = newCards;
    });
  }

  Future<Set<String>> getData() async {
    final prefs = await SharedPreferences.getInstance();
    final value = prefs.getKeys();
    print("got ${value.length} results");
    return value;
  }
}

另外还有个小建议:如果未来保存的数据变多,Column可能会出现内容溢出的问题,这时候可以把Column换成ListView.builder,支持滚动且更适合处理大量数据:

// 修改build方法里的body部分
body: myForms.isEmpty 
    ? const Center(child: Text("暂无保存的表单"))
    : ListView.builder(
        itemCount: myForms.length,
        itemBuilder: (context, index) => myForms[index],
      ),

这样调整后,你应该就能正常看到Card展示的内容啦。

内容的提问来源于stack exchange,提问作者afarre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:45:36