RecyclerView does not refresh after turning device with DialogFragment open

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 .

+6
source share
1 answer

I had a similar problem with RecyclerView. When I left-clicked to delete an item and then rotate the screen, the item was removed from my dataset, but the screen was not refreshing, as it usually does when we do the same action without rotation. It seems that adaptar.notifyItemRemoved () did not refresh the screen at all.

I use the source code of Nemanja Kovacevic , but I made some changes on it (for example, adding a click element, edit with a dialog, database support, etc.).

So, I read this post , which gave me a hint about what might happen wrong. It seems that adapter.notify was still pointing to the previous adapter sentence before rotation. Every time we rotate a new adapter, it is created in Activity: OnCreate

 public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, AddAlertDialog.OnAlertSavedListener, AlertListAdapter.OnItemDeletedListener { static ListAdapter mListAdapter; RecyclerView mRecyclerView; ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... mRecyclerView = (RecyclerView) findViewById(R.id.mainListView); mDB = new DatabaseTable(this); // Reading all alerts ArrayList<Alert> alerts = mDB.getAllAlerts(); if (mListAdapter == null) mListAdapter = new ListAdapter(this, alerts); } } 

It may not be perfect (creating static objects is not a good idea), but it solved the problem.

Hope this helps too.

0
source

All Articles