Challenge Solution - only two lines added


#1

In CrimeListFragment.

  1. First I declared local variable of class CrimeListFragment:
  1. Then I changed UpdateUI():

[code]private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getActivity());
List crimes =crimeLab.getCrimes();

    if (mAdapter == null) {
        mAdapter = new CrimeAdapter(crimes);
        mCrimeRecyclerView.setAdapter(mAdapter);
    } else {
        mAdapter.notifyItemChanged(itemPosition);
    }
}[/code]
  1. At last, I changed CrimeHolder onClick method:

public void onClick(View v) { itemPosition = mCrimeRecyclerView.getChildAdapterPosition(v); Intent intent = CrimeActivity.newIntent(getActivity(), mCrime.getId()); startActivity(intent); }


#2

That’s basically what I did, except I used getAdapterPosition() instead of getChildAdapterPosition()


#3

Impressive. The onClick method is the only place where you know which item is being tapped. I had the Holder know its position at during binding and return that. This way looks more efficient.


#4

Isn’t this solution exactly what the book warned against using in ‘For the More Curious: Why Use Fragment Arguments’ section right after the challenge?

If you switch out of the app while you’re on the CrimeFragment, the OS may reclaim memory and CrimeListFragment will lose itemPosition. To ensure that the position persists you need to use saved instance state or fragment arguments.


#5

I think that this may also cause issues when you move to chapter 11 where you gain the ability to swipe between crime details. If you capture the view clicked on in the list view and use that to index the update, what will happen when you click on one, go to the detail page, then swipe right and edit the next crime? I have not tried this so I do not know, though I believe it would introduce a bug.


#6

FYI, the solution is actually a great solution even though there is state loss.

If the memory is reclaimed and we lose the value of the itemPosition instance variable, the view is also going to be lost and everything will be recreated. Everything has to be reloaded in this case, so there’s no way to be more efficient about it.


#7

About being more efficient as regards this solution? Isn’t it possible to stash the itemPosition in the fragment’s bundle in OnSaveInstanceState and load it back in onCreateView ???


#8

You can do that, but it’s not necessary. If the saved state is being used, the view is being recreated, so everything is refreshed anyway.


#9

Ok. Maybe this is a perfect scenario of EP’s YAGNI that you were talking about.


#10

Be careful to use this method!
Challenge Deleting Crimes in Chapter 13:
- When user press on delete-icon, the crime will be remove in the list, and then the mAdapter will notify the item change. We’ll get the IndexOutOfBoundException because the index was removed before.


#11

Hey guys, here is what I did and it seems to work. I am basically checking the list for differences before and after any change is made. If a Crime object has been modified then its position can be found using findPosition(Crime c), a method I created in the CrimeLab class. Please let me know how this goes for you as I am not sure if this is the best way to solve it.

private void updateUI() {
    CrimeLab crimeLab = CrimeLab.get(getActivity());

    List<Crime> crimes = crimeLab.getCrimes();
    List<Crime> crimesListTemp = crimeLab.getCrimes();

    if (mAdapter == null) {
        mAdapter = new CrimeAdapter(crimes);
        mCrimeRecyclerView.setAdapter(mAdapter);
    } else {
        for(int i = 0; i < crimes.size(); i++) {
            if(crimes.get(i) != crimesListTemp.get(i)) {
                mAdapter.notifyItemChanged(crimeLab.findPosition(crimes.get(i)));
            }
        }
        mCrimeRecyclerView.setAdapter(mAdapter);

    }
}

In the CribeLab class, add this method.

 public int findPosition(Crime c) {
    for(Crime crime : mCrimes) {
        if(crime.getId().equals(c.getId())) {
            return mCrimes.indexOf(crime);
        }
    }
    return -1;
}

#12

Dear Niatik,
I’ve noticed that code works for chapter 10. When you start to use PageViewer it doesn’t work. Let me explain. For example, you clicked on a crime 3 and type title set solved, go to the next page also put title set unsolved. When you click on back you’ll see that crime #3 has changed title, but crime #4 doesn’t.
Guys any suggestions?


#13

Nice representation of the programming language and in from the past few time search for the help of the contact number of Kaspersky Customer Service Number and also want to see what they do after my call to them.