使用SharedPreferences填充第二个Activity的ListView问题求助
兄弟,我太懂你遇到的这个糟心问题了——在第一个Activity输入新值后,第二个Activity的ListView居然只显示一个包含整个ArrayList内容的单项,这大概率是你在SharedPreferences的存储或读取环节踩了坑,要么是把整个列表当成单个值存了,要么是读取后没正确解析成独立元素。下面给你一步步捋清楚解决方案:
可能的问题根源
通常出现这种情况,逃不开两个原因:
- 存储ArrayList时错误地把它转成单个字符串存在一个Key下,没有用SharedPreferences支持的集合存储方式;
- 读取时没把存储的内容解析成ArrayList的单个元素,反而直接把整个集合的字符串表示当成一个ListView项塞进去了。
正确的存储与读取方案
SharedPreferences本身支持存储Set<String>,或者我们可以用JSON序列化来存储ArrayList,这里给你两种靠谱的实现方式:
方式一:利用SharedPreferences的StringSet存储
第一个Activity(存储逻辑)
当你要保存EditText的输入值时,先取出已有的集合,添加新值后再存回去:
// 获取SharedPreferences实例 SharedPreferences sp = getSharedPreferences("MyPrefs", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); // 获取已有的字符串集合,没有的话新建一个 Set<String> existingSet = sp.getStringSet("my_list", new HashSet<>()); // 将EditText的新值添加到集合中 existingSet.add(editText.getText().toString().trim()); // 保存更新后的集合 editor.putStringSet("my_list", existingSet); editor.apply();
第二个Activity(读取并填充ListView)
读取集合后转成ArrayList,再传给适配器:
// 获取SharedPreferences SharedPreferences sp = getSharedPreferences("MyPrefs", MODE_PRIVATE); Set<String> stringSet = sp.getStringSet("my_list", new HashSet<>()); // 转成ArrayList(如果需要保持添加顺序,存储时换成LinkedHashSet即可) ArrayList<String> dataList = new ArrayList<>(stringSet); // 设置ListView的适配器 ListView listView = findViewById(R.id.list_view); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList); listView.setAdapter(adapter);
方式二:用JSON序列化存储ArrayList
如果需要严格保持列表的添加顺序(StringSet是无序的),推荐用JSON序列化的方式:
第一个Activity(存储逻辑)
SharedPreferences sp = getSharedPreferences("MyPrefs", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); // 先读取已有的列表 String json = sp.getString("my_list_json", null); ArrayList<String> dataList = new ArrayList<>(); if (json != null) { // 用Gson反序列化(记得在build.gradle里添加Gson依赖) dataList = new Gson().fromJson(json, new TypeToken<ArrayList<String>>(){}.getType()); } // 添加新值 dataList.add(editText.getText().toString().trim()); // 序列化后存储 String newJson = new Gson().toJson(dataList); editor.putString("my_list_json", newJson); editor.apply();
第二个Activity(读取逻辑)
SharedPreferences sp = getSharedPreferences("MyPrefs", MODE_PRIVATE); String json = sp.getString("my_list_json", null); ArrayList<String> dataList = new ArrayList<>(); if (json != null) { dataList = new Gson().fromJson(json, new TypeToken<ArrayList<String>>(){}.getType()); } // 填充ListView ListView listView = findViewById(R.id.list_view); ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList); listView.setAdapter(adapter);
关键注意点
- 绝对不要直接把
ArrayList.toString()的结果存成单个字符串,不然读取后整个字符串会被当成一个ListView项; - 如果用StringSet,记得它是无序的,要保持顺序就用
LinkedHashSet代替HashSet存储; - 确保适配器的数据源是包含单个元素的ArrayList,别犯把整个集合对象作为一个元素添加到列表里的低级错误(比如别写
adapter.add(dataList.toString()),直接把dataList传给适配器就行)。
内容的提问来源于stack exchange,提问作者Skye
相关产品推荐
相关产品推荐

