gedreht wurde. Ich habe einen RecyclerView
innerhalb eines AppCompatActivity
. Artikeleinfügungen und -änderungen werden nach dem Drehen des Geräts korrekt angezeigt und animiert.RecyclerView wird nicht aktualisiert, nachdem das Gerät mit einem geöffneten DialogFragment
Das Problem tritt auf, wenn Sie:
- Tippen Sie auf ein Element in der
RecyclerView
. - Eine
DialogFragment
öffnet die Abfrage, wenn Sie das Element löschen möchten. - Drehen Sie das Gerät.
- Bestätigen Sie das Löschen im Dialog.
- Überprüfen Sie die Array-Liste. Der Artikel wurde gelöscht.
- Die
RecyclerView
zeigt immer noch das Element.
Versuchte notifyDataSetChanged
statt notifyItemRemoved
verwenden, aber hat nicht funktioniert entweder, weil das Element noch in der RecyclerView
gezeigt werden wird.
Dies geschieht mit jeder Version von Android.
Vereinfachte Code, wie der Prozess gehandhabt wird:
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;
}
}
Wie kann ich die RecyclerView
richtig zu arbeiten?
Edit 1:
Ich habe andere RecyclerView
s, in denen diese korrekt funktioniert. Der einzige Unterschied ist, dass diese innerhalb Fragment
s statt AppCompatActivity
sind. Ich vermute, dass dies etwas mit den Ereignissen onDetachedFromWindow
und onAttachedToWindow
der RecyclerView
zu tun hat.
Edit 2:
Wenn der Dialog geschlossen wird (Schritt 4) und wieder geöffnet es funktioniert wie erwartet.
bearbeiten 3:
Wenn die RecyclerView
als Fragment
extrahiert wird das Problem verschwindet und wie vorgesehen funktioniert. Es ist unmöglich, den oben beschriebenen Anwendungsfall in Verbindung mit AppCompatActivity
anstelle einer Fragment
korrekt zu behandeln.
Wenn Sie auf den Dialog klicken, sollte er verschwinden und das Element in der Liste löschen. Wie kommt es, dass der Dialog bleibt, wenn Sie die Ausrichtung ändern und die Daten löschen? –
@ReazMurshed Der Anwendungsfall ist folgender: Sie klicken auf ein Element, um es zu löschen. Es zeigt einen Bestätigungsdialog mit den Optionen ('Abbrechen' und 'Löschen'). Sie klicken auf keine der Optionen. Sie drehen das Gerät. Der Dialog ist noch offen. Sie wählen dann die Option "Löschen", um den Artikel zu löschen. Der Dialog wird geschlossen. Der Artikel wurde aus der Datenbank gelöscht. Das 'RecyclerView' wird nicht entsprechend aktualisiert, es zeigt immer noch das gelöschte Element an. – OneEyeQuestion
Dies ist keine richtige Lösung, aber auf jeden Fall kann dieser Hack den Trick machen, den Sie wollen. Sie können die Orientierungsänderung leicht in 'onConfigurationChange' erkennen und den auf dem Bildschirm angezeigten Dialog schließen. Der auf dem Bildschirm angezeigte Dialog bezieht sich nicht auf den Aktivitäts-/Fragmentlebenszyklus und deshalb bleibt er auf dem Bildschirm. –