I have a RecyclerView inside a AppCompatActivity . After turning the device, inserts and changes to elements are displayed and animated.
The problem arises if you:
- Click on an item in
RecyclerView . - A
DialogFragment opens a request if you want to delete an item. - Rotate the device.
- Confirm the deletion in the dialog box.
- Check the list of arrays. Item deleted.
RecyclerView still shows the item.
Tried to use notifyDataSetChanged instead of notifyItemRemoved , but did not work because the item is still displayed in RecyclerView .
This happens with any version of Android.
Simplified processing code:
public class MyAppCompatActivity extends AppCompatActivity { int positionOfDeletedItem; MyObjectRecyclerViewAdapter adapter; ArrayList<MyObject> someTestData; MyItemDeletionHandler deletionHandlerRemover; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.my_activity_layout); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); positionOfDeletedItem = 1; deletionHandlerRemover = new MyItemDeletionHandler(this); someTestData = new ArrayList<MyObject>(3); someTestData.add(new MyObject("A")); someTestData.add(new MyObject("B")); someTestData.add(new MyObject("C")); recyclerView.setHasFixedSize(true); recyclerView.setLayoutManager(new LinearLayoutManager(this)); adapter = new MyObjectRecyclerViewAdapter(new MyAdapterOnClickEvent.OnItemClick() { @Override public void onClick(int posicion, int idViaje, View view) { String tag = "Some tag value"; FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); Fragment prev = getSupportFragmentManager().findFragmentByTag(tag); if(prev != null) ft.remove(prev); ft.addToBackStack(null); DialogFragment newFragment = MyDeletionConfirmationDialog.newInstance(deletionHandlerRemover); newFragment.show(ft, tag); } }, someTestData); recyclerView.setAdapter(adapter); } private final static class MyItemDeletionHandler extends Handler { private final WeakReference<MyAppCompatActivity> theActivity; private MyItemDeletionHandler(MyAppCompatActivity act) { theActivity = new WeakReference<MyAppCompatActivity>(act); } @Override public void handleMessage(Message msg) { MyAppCompatActivity activity = theActivity.get(); if(activity != null) { if(msg.what == 1) { activity.deleteTheItem(); } } } } public void deleteTheItem() { someTestData.remove(positionOfDeletedItem); adapter.notifyItemRemoved(positionOfDeletedItem); } } public class MyDeletionConfirmationDialog extends DialogFragment { private Message handlerMessage; public static MyDeletionConfirmationDialog newInstance(Handler callbackHandler) { MyDeletionConfirmationDialog myDialog = new MyDeletionConfirmationDialog(); Bundle args = new Bundle(); args.putParcelable("handlerMessage", callbackHandler.obtainMessage(1, true)); myDialog.setArguments(args); return myDialog; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); handlerMessage = getArguments().getParcelable("handlerMessage"); } @Override @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()); alertDialogBuilder.setMessage("Some message"); alertDialogBuilder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { final Message toSend = Message.obtain(handlerMessage); toSend.sendToTarget(); } }); alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); Dialog dialog = alertDialogBuilder.create(); dialog.setCanceledOnTouchOutside(true); return dialog; } }
How can I get RecyclerView to work correctly?
Change 1:
I have another RecyclerView in which this works correctly. The only difference is that inside the Fragment instead of AppCompatActivity . I suspect this has something to do with the onDetachedFromWindow and onAttachedToWindow RecyclerView events.
Edit 2:
If the dialog is closed (step 4) and opened again, it works as expected.
Edit 3:
If the RecyclerView is retrieved as a Fragment , the problem disappears and works as intended. You cannot use the use case described above in combination with AppCompatActivity instead of Fragment .
source share