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

从Firebase获取字符串后无法填充RecyclerView适配器问题

解决Firebase Realtime Database数据填充RecyclerView失败及SharedPreferences存储问题

问题分析

  1. 数据解析错误:Firebase中art节点下是对象数组,每个子节点是键值对结构(如{"MrIncredibleArt": "stringexample4"}),直接调用artSnapshot.getValue()得到的是Map而非目标字符串,导致无法正确提取数据。
  2. 异步加载时序问题:Firebase数据请求是异步操作,你在onCreateView中初始化适配器时,Firebase还未返回数据,此时asciiArts为空列表,适配器自然无法显示内容。
  3. 未实现SharedPreferences存储逻辑:尚未完成将Firebase数据存入SP、再从SP读取填充列表的需求。

解决方案

步骤1:修正Firebase数据解析逻辑

遍历每个子节点的键值对,提取字符串值:

private void initAsciiArts_Art() {
    DatabaseReference databaseRef = FirebaseDatabase.getInstance().getReference().child("art");
    databaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NotNull DataSnapshot dataSnapshot) {
            List<String> tempList = new ArrayList<>();
            for (DataSnapshot artSnapshot : dataSnapshot.getChildren()) {
                // 遍历对象内的键值对,取出字符串值
                for (DataSnapshot innerSnapshot : artSnapshot.getChildren()) {
                    String asciiArt = innerSnapshot.getValue(String.class);
                    if (asciiArt != null) {
                        tempList.add(asciiArt);
                    }
                }
            }
            // 将数据存入SharedPreferences
            saveToSharedPreferences(tempList);
            // 从SP读取数据并更新列表和适配器
            loadFromSharedPreferences();
        }

        @Override
        public void onCancelled(@NotNull DatabaseError databaseError) {
            Log.e("Firebase", "Failed to retrieve art data: " + databaseError.getMessage());
        }
    });
}

步骤2:实现SharedPreferences存储与读取

使用Gson将列表转为JSON字符串存储,读取时再转回列表:

// 存储数据到SharedPreferences
private void saveToSharedPreferences(List<String> dataList) {
    SharedPreferences sp = requireContext().getSharedPreferences("AsciiArtsPrefs", Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sp.edit();
    Gson gson = new Gson();
    String json = gson.toJson(dataList);
    editor.putString("art_list", json);
    editor.apply();
}

// 从SharedPreferences读取数据,返回是否读取成功
private boolean loadFromSharedPreferences() {
    SharedPreferences sp = requireContext().getSharedPreferences("AsciiArtsPrefs", Context.MODE_PRIVATE);
    String json = sp.getString("art_list", null);
    if (json != null) {
        Gson gson = new Gson();
        Type type = new TypeToken<List<String>>() {}.getType();
        asciiArts.clear();
        asciiArts.addAll(gson.fromJson(json, type));
        return true;
    }
    return false;
}

步骤3:调整适配器初始化与更新逻辑

优先从SP读取数据,无数据时再请求Firebase;数据加载完成后通知适配器更新:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.meme_fragment, container, false);
    RecyclerView recyclerView = view.findViewById(R.id.recycler_view_meme);
    recyclerView.setNestedScrollingEnabled(false);
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    recyclerView.setHasFixedSize(true);

    // 初始化适配器(初始为空列表)
    MemeAdapter_Meme adapter = new MemeAdapter_Meme(asciiArts, requireContext(), this);
    recyclerView.setAdapter(adapter);

    // 先从SP读取数据,读取成功则更新适配器,否则请求Firebase
    if (loadFromSharedPreferences()) {
        adapter.notifyDataSetChanged();
    } else {
        initAsciiArts_Art();
    }

    return view;
}

// 更新适配器的方法
private void updateRecyclerViewAdapter() {
    RecyclerView recyclerView = getView().findViewById(R.id.recycler_view_meme);
    MemeAdapter_Meme adapter = (MemeAdapter_Meme) recyclerView.getAdapter();
    if (adapter != null) {
        adapter.notifyDataSetChanged();
    }
}

额外配置

确保已添加Gson依赖(在Module级别的build.gradle中):

implementation 'com.google.code.gson:gson:2.10.1'

同时检查Firebase Realtime Database的读写权限配置,确保应用能正常读取数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:27:45