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

如何用SharedPreferences保存RecyclerView中CardView的图片状态?

Solution: Persist CardView Image State with SharedPreferences

Got it, let's work through this step by step. You want each CardView's image state to stick around even after closing the app or navigating back—SharedPreferences is exactly the right tool for this. Here's how to modify your adapter and handle the logic properly:

1. Fix the ViewHolder Global Variable Bug

First up, remove the global holder variable in your adapter. It’s unnecessary and will cause weird issues with RecyclerView’s view recycling. Your onCreateViewHolder should just create and return a ViewHolder locally:

// Delete this line from your adapter class
// private ViewHolder holder;

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_lesson_rec_view, parent, false);
    return new ViewHolder(view); // Create and return directly, no global holder needed
}

2. Integrate SharedPreferences for State Storage

We’ll use each lesson’s lessonId as a unique key to store its image state. This way, every lesson’s state stays independent.

a. Load Saved State in onBindViewHolder

Instead of always loading the plain image, check SharedPreferences first to see if a saved state exists, then load the matching image:

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
    Log.d(TAG, "onBindViewHolder: called");
    Lesson currentLesson = lessons.get(position);
    holder.txtLessons.setText(currentLesson.getLessonNumber());
    
    final int imgSad = R.mipmap.sad;
    final int imgSmile = R.mipmap.smile;
    final int imgPlain = R.mipmap.plain;

    // Get our SharedPreferences instance (named "LessonStates" to keep things organized)
    SharedPreferences prefs = context.getSharedPreferences("LessonStates", MODE_PRIVATE);
    // Read the saved state for this lesson—default to 0 (plain image) if no state exists
    int imageState = prefs.getInt("lesson_" + currentLesson.getLessonId(), 0);

    // Pick the right image based on the saved state
    int imageToLoad = imgPlain;
    switch (imageState) {
        case 1:
            imageToLoad = imgSmile;
            break;
        case 2:
            imageToLoad = imgSad;
            break;
        default:
            imageToLoad = imgPlain;
    }

    Glide.with(context)
            .asBitmap()
            .load(imageToLoad)
            .into(holder.imageView);

    // ... rest of your click listener code
}

b. Update State When Returning from the Lesson Activity

When the user finishes with Lesson1Activity and navigates back, we need to save the new state (e.g., mark it as completed with the smile image). Add this code to Lesson1Activity:

// Inside Lesson1Activity.java
@Override
protected void onDestroy() {
    super.onDestroy();
    // Save the state for lesson 1 (we'll use 1 to represent the smile image)
    SharedPreferences prefs = getSharedPreferences("LessonStates", MODE_PRIVATE);
    prefs.edit().putInt("lesson_1", 1).apply();
}

If you only want to update the state after a specific action (like clicking a "Complete" button in Lesson1Activity), move the prefs.edit() code to that button’s onClick listener instead.

c. Refresh the RecyclerView When Returning

To make the image update right away when the user comes back to the RecyclerView screen, override onResume in the parent Activity (the one holding the RecyclerView):

// Inside your Activity with the RecyclerView
@Override
protected void onResume() {
    super.onResume();
    // Tell the adapter to reload data and update all views
    yourLessonAdapter.notifyDataSetChanged();
}

Replace yourLessonAdapter with the actual instance of LessonRecViewAdapter in your Activity.

3. Optional: Update Image Immediately on Click (If Needed)

If you want the image to change as soon as the user taps the CardView (before navigating), add the state save code directly to the onClick listener:

holder.cardView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        int lessonId = currentLesson.getLessonId();
        switch (lessonId) {
            case 1:
                // Save the state first
                SharedPreferences prefs = context.getSharedPreferences("LessonStates", MODE_PRIVATE);
                prefs.edit().putInt("lesson_" + lessonId, 1).apply();
                // Update the current CardView's image right away
                Glide.with(context)
                        .asBitmap()
                        .load(imgSmile)
                        .into(holder.imageView);
                // Navigate to Lesson1Activity
                Intent intent = new Intent(context, Lesson1Activity.class);
                context.startActivity(intent);
                break;
            case 2:
                Toast.makeText(context, "Comming Soon", Toast.LENGTH_SHORT).show();
                break;
            default:
                break;
        }
    }
});

Quick Notes

  • We use LessonStates as the SharedPreferences file name to keep all lesson states grouped together.
  • Each lesson’s state uses a unique key like lesson_1 or lesson_2 to avoid conflicts.
  • Using apply() instead of commit() for edits is better—it’s asynchronous and won’t block the main thread.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:17:37