Notify RecyclerView to refresh changed items only


#1

I’m following this great book and I’ve learned a lot.

My question is about how to notify RecyclerView only refresh the changed items. Say I have 3 Crimes in the list, I click the first, then it starts ViewPager, I swipe to 2nd and 3rd and change them. How can I notify the RecyclerView only refresh the 2nd and 3rd items instead of using notifyDataSetChanged()

I tried getActivity().setResult() using different keys for different fragment in CrimeFragment. But onActivityResult in CrimeListFragment can only get the last one…


#2

I am wondering about this too because I did the challenge from Chapter 10 regarding only having CrimeListFragment update the item selected rather than the entire list of Crimes even though only one can change. I ended up storing the position clicked in the Holder onClick then update that one position with notifyItemChanged(). I am wondering if CrimePagerActivity should store a list of Crimes that you swipe to and then pass that back to CrimeListFragment. I going to play out more of the book to see if this gets addressed but that is my first idea for solving this.


#4

That’s my solution:
public class CrimePagerActivity extends AppCompatActivity {


public static ArrayList mChangeList = new ArrayList<>();

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        mChangeList.add(position);
    }

    @Override
    public void onPageSelected(int position) {

    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
});

}
}

and changes in CrimeListFragment.class:

private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getActivity());
List crimes = crimeLab.getCrimes();
if(mAdapter==null){
mAdapter = new CrimeAdapter(crimes);
mCrimeRecyclerView.setAdapter(mAdapter);
} else {
for(Integer changed : CrimePagerActivity.mChangeList) {
** mAdapter.notifyItemChanged(changed);**
}
}

But it updates even reviewed Crimes, so it’s not perfect


#5
  1. I created a static ArrayList in CrimePagerActivity
public class CrimePagerActivity extends AppCompatActivity {
    public static List<Integer> sUpdatedCrimes;
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        sUpdatedCrimes = new ArrayList<>();
    }
}
  1. Inserted updated crimeIDs into this array in CrimeFragment
void crimeUpdated() {
    List<Integer> updatedCrimes = CrimePagerActivity.sUpdatedCrimes;
    updatedCrimes.add(mCrimePosition);
    Intent intent = new Intent();
    intent.putExtra(CrimePagerActivity.EXTRA_CRIME_ID, (Serializable) updatedCrimes);
    getActivity().setResult(Activity.RESULT_OK, intent);
}
  1. Then looped through this Arraylist from the result in CrimeListFragment
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CRIME) {
        if (resultCode == Activity.RESULT_OK) {
            ArrayList<Integer> updatedPositions = data.getIntegerArrayListExtra(CrimePagerActivity.EXTRA_CRIME_ID);
            for (Integer position : updatedPositions) {
                Log.d(TAG, "Updating Crimes: " + position);
                mCrimeAdapter.notifyItemChanged(position);
            }
        }
    }
}