ListView选中项关闭APP后仍高亮:SharedPreferences保存读取求助
Hey there! I see you've already started working with SharedPreferences to persist your ListView selections, but we need to tweak your code to properly save the selection state (not just the list items) and add the logic to restore those highlights when your app reloads. Let's break this down step by step:
First: Fix Your Save Logic
Right now, your saved() method is saving the list items and a single position, but it's not storing the isSelected boolean array that tracks which items are highlighted. Let's update that to save every item's selection status:
public boolean saveSelectionState() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor mEdit1 = sp.edit(); // Save the size of the selection array (in case your list changes later) mEdit1.putInt("Selection_Size", isSelected.length); // Save each item's selection status for(int i = 0; i < isSelected.length; i++) { mEdit1.putBoolean("IsSelected_" + i, isSelected[i]); } // Optional: Save list items if they might change between sessions mEdit1.putInt("List_Size", list_items.size()); for(int i = 0; i < list_items.size(); i++) { mEdit1.putString("List_Item_" + i, list_items.get(i).toString()); } return mEdit1.commit(); }
Also, let's update your item click listener to toggle selections (so users can deselect items too) and call the updated save method:
text_listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // Toggle the selection state instead of setting it to true permanently isSelected[position] = !isSelected[position]; text_listview.setItemChecked(position, isSelected[position]); // Update background color based on selection if (isSelected[position]) { view.setBackgroundColor(getResources().getColor(R.color.colorBlue)); } else { // Reset to your default list item background color view.setBackgroundColor(getResources().getColor(android.R.color.white)); } // Save the updated selection state saveSelectionState(); } });
Don't forget to set the ListView's choice mode (this ensures setItemChecked works as expected):
text_listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); // Use CHOICE_MODE_SINGLE if you only allow one selection
Second: Add Restore Logic
Now we need to read the saved state when your activity/fragment starts. Add this method and call it after initializing your ListView and adapter:
private void restoreSelectionState() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); // Restore list items first (if you saved them) int listSize = sp.getInt("List_Size", 0); if (listSize > 0) { list_items.clear(); for(int i = 0; i < listSize; i++) { String item = sp.getString("List_Item_" + i, ""); list_items.add(item); } arrayAdapter.notifyDataSetChanged(); } // Restore selection state int selectionSize = sp.getInt("Selection_Size", 0); if (selectionSize > 0 && selectionSize == isSelected.length) { for(int i = 0; i < selectionSize; i++) { isSelected[i] = sp.getBoolean("IsSelected_" + i, false); text_listview.setItemChecked(i, isSelected[i]); } } }
Call this in onCreate after setting up your adapter:
// After initializing arrayAdapter and attaching it to the ListView restoreSelectionState();
A Quick Fix for Scrolling Items
If your ListView has more items than fit on screen, getChildAt(i) might return null for off-screen items. To ensure highlights stay correct when scrolling, override your adapter's getView() method:
arrayAdapter = new ArrayAdapter(this, R.layout.list_item, list_items) { @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); // Set background color based on saved selection state if (isSelected[position]) { view.setBackgroundColor(getResources().getColor(R.color.colorBlue)); } else { view.setBackgroundColor(getResources().getColor(android.R.color.white)); } return view; } };
This way, every item will show the correct highlight state whenever it's rendered on screen.
内容的提问来源于stack exchange,提问作者McLarvel

