6

Hi Ich entwickle eine App, die Karten verwendet.Dismissed Dialogfragment wird wieder angezeigt, wenn App fortgesetzt wird

Ich benutze Fragment Activity und ein Fragment mit dem Namen Fragment-A.

In Fragment-A gibt es eine Schaltfläche. Wenn Sie auf diese Schaltfläche klicken, wird ein Dialogfragment angezeigt, das eine Karte mit einem zuvor vom Server empfangenen Standort anzeigt.

Nehmen wir an, dieses Dialogfragment ist DialogFragment-B.

Es hat eine Schaltfläche zum Schließen, eine Schaltfläche, um zur Google Maps App zu navigieren, um Wegbeschreibungen zu erhalten.

Wenn Benutzer zu DialogFragment-B navigiert und zum Fragment-A zurückkehrt, kann durch Klicken auf die Schaltfläche zum Schließen alles ordnungsgemäß ausgeführt werden.

Wenn der Benutzer jedoch auf die Schaltfläche Zurück klickt, wird das vorhandene Dialogfeldfragment normal geschlossen und die App funktioniert normal.

Aber wenn der Benutzer dann Home-Taste gedrückt oder einen Anruf empfangen und onResume heißt, obwohl das DialogFragment-B früher entlassen wird, erscheint es und drücken nahe stürzt die App mit einer Null-Zeiger Ausnahme

Hier Mein Code um das DialogFragment-B zu öffnen.

FragmentManager fm = getFragmentManager(); 
    FragmentTransaction ft = fm.beginTransaction(); 
    android.app.Fragment prev = fm.findFragmentByTag(MY_MAP); 
    if (prev != null) { 
     ft.remove(prev); 
    } 
    MyMapFragmentDialog newFragment = MyMapFragmentDialog 
      .newInstance(eachPost); 
    newFragment.show(ft, MY_MAP); 

In DialogFragment-B auf Schließen-Schaltfläche klicken, rufe ich MyMapFragmentDialog.this.dismiss();

Bitte, wenn jemand dieses Problem begegnet und überwunden, führen Sie mich durch.

+0

Ich denke, Sie vernachlässigen die Transaktion zu verpflichten: 'ft.remove (prev) .commit()' oder fügen Sie eine andere Zeile wie 'ft.commit();' –

+0

Versuchen Sie den 'MyMapFragmentDialog' innerhalb der if-Schleife. Das 'prev' wird null und du fügst das Fragment hinzu – GoCrazy

Antwort

2

Update: Die Antwort von Kalina ist eine elegantere und einfachere Lösung - wie ich später herausgefunden habe!

Ich bin vor dem gleichen Problem in einem meiner apps, und die Antwort nicht überall zu finden, ging durch den Quellcode der DialogFragment-Klasse, die unter:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/DialogFragment.java#DialogFragment.onDismiss%28android.content.DialogInterface%29

und dort ich den wahrscheinlichen Grund in einem Kommentar geschrieben gefunden, in der Quelle onDismiss (DialogInterface Dialog) Methode:

// Note: we need to use allowStateLoss, because the dialog 
// dispatches this asynchronously so we can receive the call 
// after the activity is paused. Worst case, when the user comes 
// back to the activity they see the dialog again. 

Was ich von dieser verstanden ist, dass die Entlassung ist nicht im Instanzstatus gespeichert, und wenn die Aktivität fortgesetzt wird, wird sie sofort im Rahmen der Wiederherstellung des Instanzstatus erneut angezeigt - vorausgesetzt, das Fragment wurde nie gelöscht. Als ein asynchrones Ereignis, gibt es keinen sicheren Weg, die entlassen zu begehen, ohne eine

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 

Ausnahme und damit Absturz zu riskieren, was wahrscheinlich ist, warum die Autoren der Klasse es auf diese Weise zu tun gewählt haben.

Die Lösung, die für mich arbeitete, war getrennt, um den Zustand des DialogFragment zu überwachen, von:

  • es in einer Klassenvariablen speichern (hier bezeichnet als ‚Dialog‘)
  • Überschreiben der onDismiss (DialogInterface dialog) Methode und
  • einen booleschen dialogDismissed flag auf wahr
Einrichten

-

@Override 
public void onDismiss(DialogInterface dialog) { 
    // dialogDismissed is a Class level variable in the containing Activity, 
    // must be set to false each time the DialogFragment is shown 
    dialogDismissed = true; 
} 
  • Hinweis: Wenn der DialogFragment eine separate Klasse ist, dann dann im Aktivitäts eines Verfahren muß von der onDismiss aufgerufen werden, dies zu tun, vielleicht durch eine Schnittstelle einrichten

  • muss dieser Flag dann in der Aktivität onResume geprüft werden() und ein (nach Überprüfung, dass der Dialog nicht null ist) gezwungen dismiss:

-

@Override 
public void onResume() { 
super.onResume(); 
//... 
if (dialogDismissed && dialog != null) { 
     dialog.dismiss(); 
    }  
} 
10

hatte ich das gleiche Problem und es wurde, indem sie sicher, dass ich super.onDismiss(dialog) im onDismiss Methode meiner DialogFragment Unterklasse nennen gelöst.

+0

Ich hatte das gleiche Problem, das meine behoben. – qtyq

Verwandte Themen