0

I have read the following articles,

  1. Passing data back to previous fragment from current fragment

  2. Passing data between Fragments in View Pager

  3. How can I transfer data from one fragment to another fragment android

  4. Android: Best Approach to pass data between viewpager fragments

I have not been able to figure to figure out how to inform the parent fragment that a row has been deleted in the child fragment. My parent fragment consists of a recycler view with multiple rows. I want to rerender(??) the recycler view without the deleted row. Any help would be appreciated.

This is my Github repo: https://github.com/manoflogan/android-projects/blob/menu/02-Criminalntent/

This is my use case:

  1. When the app is started, the user will see an empty view. An image of an empty view

  2. If they want to add a new crime object, they will click/tap on + icon in the menu bar as seen in previous image

  3. This action generates an intent mapped to another activity https://github.com/manoflogan/android-projects/blob/menu/02-Criminalntent/app/src/main/java/com/krishnanand/criminalintent/CrimeListFragment.java#L67.

  4. This loads an activity in which a ViewPager is defined, and in which a fragment is associated https://github.com/manoflogan/android-projects/blob/menu/02-Criminalntent/app/src/main/java/com/krishnanand/criminalintent/CrimePagerActivity.java#L60. The crime object is created as shown here.

The image shows the crime object that has been created. Crime object created. This show the view when the user presses the back button as shown below. Multiple rows created and displayed after user presses the back button

  1. When the item is deleted, then I want to inform the parent fragmment that a row in the recycler view has been deleted. I am trying to return to the Fragment with the Recycler View here. https://github.com/manoflogan/android-projects/blob/menu/02-Criminalntent/app/src/main/java/com/krishnanand/criminalintent/CrimeFragment.java#L81

This is the method in which I am trying to update the recycler that a row has been deleted. https://github.com/manoflogan/android-projects/blob/menu/02-Criminalntent/app/src/main/java/com/krishnanand/criminalintent/CrimeListFragment.java#L110

If I have N rows, and if I want to delete any row except the last row, the app crashes with the following error.

--------- beginning of crash 2018-11-23 17:40:49.932 13876-13876/com.krishnanand.criminalintent E/AndroidRuntime: FATAL EXCEPTION: main Process: com.krishnanand.criminalintent, PID: 13876 java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{6d1120f position=1 id=-1, oldPos=1, pLpos:-1 scrap [attachedScrap] tmpDetached no parent} android.support.v7.widget.RecyclerView{4220554 VFED..... ......ID 0,0-1080,1584 #7f070032 app:id/crime_recycler_view}, adapter:com.krishnanand.criminalintent.CrimeListFragment$CrimeAdapter@3140cfd, layout:android.support.v7.widget.LinearLayoutManager@42ccdf2, context:com.krishnanand.criminalintent.CrimeListActivity@95fdd1a at android.support.v7.widget.RecyclerView$Recycler.validateViewHolderForOffsetPosition(RecyclerView.java:5715) at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5898) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858) at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854) at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612) at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3875) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3639) at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1877) at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:407) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949) at android.view.Choreographer.doCallbacks(Choreographer.java:761) at android.view.Choreographer.doFrame(Choreographer.java:693) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Amin Mozhgani
  • 604
  • 1
  • 7
  • 22
manoflogan
  • 31
  • 8

1 Answers1

0

Its not a good idea to have a single list object and modify it from different places in the code. Instead of passing the List in the constructor of the adapter, you should create a method in the CrimeAdapter called setCrimes(List crime).

private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {

    private List<Crime> mCrimes;

    public void setCrimes(List<Crime> crimes){
          this.crimes = crimes;
          notifyDataSetChanged();
    }  

    @Override
    public int getItemCount() {
      return mCrimes != null ? mCrimes.size() : 0;
    }
  }

Usually you need to create a copy of the List and make modifications to it i.e add, remove etc and then set that list.

You can use ViewModel and LiveData to share the data between your Fragments.

https://developer.android.com/reference/android/arch/lifecycle/ViewModel https://developer.android.com/topic/libraries/architecture/livedata

AJAY PRAKASH
  • 1,110
  • 7
  • 8