使用自定义对象和Gson的ArrayList还原RecyclerView状态时ArrayIndexOutOfBoundsException的解决方案

时间:2019-02-21 22:10:05

标签: android arraylist android-recyclerview gson sharedpreferences

我有一个RecyclerView,其中ViewHolder中的视图/数据(图像,标题,描述)是使用自定义对象Challenge的getter方法检索的。

我还有一个类型为ChallengeArrayList<Challenge> mChallenges)的ArrayList,在其中添加了所有挑战,后来在初始化它时将其作为RecyclerView.Adapter子类的参数传递。

我的ViewHolder的{​​{1}}中也有一个复选框,因此用户可以选择所需的挑战,这些选择的挑战将保存在名为RecyclerView的其他ArrayList<Challenge>上。这就是它们被添加的方式。

currentSelectedChallenges

当用户通过返回按钮或关闭应用程序离开包含RecyclerView的片段时,我会使用Gson使用SharedPreferences来保存选择的挑战@Override public void onChallengeChecked(int position) { // method of interface if (!currentSelectedChallenges.contains(mChallenges.get(position))){ currentSelectedChallenges.add(mChallenges.get(position)); } } ,如下所示:

ArrayList<Challenge> currentSelectedChallenges

然后通过以下方式在片段的onRestore方法上恢复currentSelectedChallenges:

@Override
public void onPause() {
    super.onPause();

    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);

    SharedPreferences.Editor editor = sharedPreferences.edit();

    Gson gson = new Gson();

    Type type = new TypeToken<ArrayList<Challenge>>(){}.getType();

    String json = gson.toJson(currentSelectedChallenges, type);

    editor.putString("selected challenges", json);

    editor.apply();
}

当我尝试在ViewHolder中恢复CheckBox的选中状态时,我得到了@Override public void onResume() { super.onResume(); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); Gson gson = new Gson(); String json = sharedPreferences.getString("selected challenges", null); Type type = new TypeToken<ArrayList<Challenge>>() { }.getType(); currentSelectedChallenges = gson.fromJson(json, type); if (currentSelectedChallenges == null) { currentSelectedChallenges = new ArrayList<>(); } else { for (int i = 0; i < currentSelectedChallenges.size(); i++) { int index = mChallenges.indexOf(currentSelectedChallenges.get(i)); mChallenges.get(index).setChecked(true); } mChallengesAdapter.notifyDataSetChanged(); } } ,因为在ArrayIndexOutOfBoundsExceptions中找不到currentSelectedChallenges.get(i),因此它返回-1。我已经记录了挑战,即使我可以使用setter方法并且将检索相同的数据,这些对象也具有不同的ID。

我试图欺骗Android并使用了它:

mChallenges

它确实在UI中打勾了用户检查过的挑战,但是当我再次单击CheckBox时,它无法检测到我的点击,因此我知道这不是正确的解决方案。

谁能解释我应该如何正确解决这个问题?

1 个答案:

答案 0 :(得分:0)

Lemma work : (forall p q : Prop, (p->q)->(~q->~p)).
Proof.
intros p q.
intros p_implies_q not_q_implies_not_p.
refine (not_q_implies_not_p).
refine (p_implies_q).
Qed.

返回-1,因为它比较参考而不是您感兴趣的数据。 您应该覆盖mChallenges.indexOf(currentSelectedChallenges.get(i)) 类的equalshashCode

Challenge