0

Recht auf Fragment jetzt bin ich mit: -Callback-Funktion did't Auslöser, wenn sie von DialogFragment Aufruf

1) Aktivität, die die Haupttätigkeit ist, die von AppCompactActivity erstreckt.

2) fragment Klasse, die von fragment erstreckt, das ist das Fragment, das (1)- ProfileTeacherActivity.java

3) Fragment Klasse von Hauptaktivität bezeichnet wurde, die von DialogFragment erstreckt, dieser Dialog Aufruf von Fragment (2)- ModalBox.java

Also, im Grunde ist dies nur ein einfacher Ablauf der Ausführung. Zu Beginn, die Anwendungen zeigen die main activity (1) Schublade, die ein paar Links als Beispiel ein Profil Link haben, wenn Sie auf diesen Link klicken, ruft die Anwendung fragment (2) Details des Profils mit einem Bearbeitungsschaltfläche aufrufen. Nach dem Klicken auf die Schaltfläche "Bearbeiten" rufen die Anwendungen DialogFragment (3) auf, die einige von EditText zum Bearbeiten des Benutzerprofils enthalten.

Was ich erreichen möchte, ist, nach der Bearbeitung des Benutzerprofils und erfolgreich in der Datenbank gespeichert, ich habe versucht, Benutzerdaten zurück zu fragment (2) senden, nur um die neuesten Informationen anzuzeigen, leider hat es nicht funktioniert.

Hier ist, was ich versucht habe:

1) Erstellen von Schnittstellen innerhalb DialogFragment (3)- ModalBox.java

public class ModalBox extends DialogFragment{ 

    .... 
    public interface EditProfileModalBoxInterface { 
    void onFinishEditProfile(HashMap<String, String> dataPassing); 
    } 
    ... 
    ... 
} 

2) Innerhalb DialogFragment ich habe auch .setPositiveButton Funktion für OK Taste. - ModalBox.java

public class ModalBox extends DialogFragment{ 
    ...  
    ... 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     ... 
     builder 
     .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
      public void onClick(final DialogInterface dialog, int id) { 
       // At here i'm using retrofit2 http library 
       // to do updating stuff 
       // and inside success's callback of retrofit2(asynchronous) 
       // here i call the below function to send data 
       // dataToSend is a HashMap value 
       sendBackResultToParent(dataTosend); 
      } 
     }) 
     .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int id) { 
       // User cancelled the dialog 
      } 
     }); 
     ..... 
    } 

    // Function called inside success's callback of retrofit2 
    public void sendBackResultToParent(HashMap<String, String> data) { 
     // instantiated interface 
     EditProfileModalBoxInterface ls=(EditProfileModalBoxInterface)getTargetFragment(); 
     // declaring interface's method 
     ls.onFinishEditProfile(data); 
    } 
} 

3) Schließlich, ich bin implementiert jene Schnittstelle innerhalb fragment(2)- ProfileTeacherActivity.java

public class ProfileTeacherActivity extends Fragment 
     implements ModalBox.EditProfileModalBoxInterface{ 

    public View onCreateView(LayoutInflater inflater, 
        ViewGroup container, Bundle savedInstanceState) { 
     ..... 
     ..... 
    } 

    // At here the interface's method did't triggered 
    @Override 
    public void onFinishEditProfile(HashMap dataPassedFromDialog) { 
     Toast.makeText(getActivity(), "Testing...." , Toast.LENGTH_LONG).show(); 
    } 

} 

Was ich tue, ist verwirrt im Moment bin, passiert das Problem nur, wenn ich dies genannt Funktion sendBackResultToParent(dataTosend); innerhalb von Retrofit2 Erfolg Callback, wird ausgelöst, wenn außerhalb von ihm anrufen. Ich nehme an, der Async namens verursacht dies. Wenn ich Promise oder etwas Ähnliches verwenden könnte, oder gibt es einen Workaround?

Die folgenden bestehenden Lösungen hat in meinem Fall nicht:

mich für weitere Eingaben Fragen Sie, ob oben Anwendungsfall nicht klar tat genug oder falsch verstanden. Danke für die Hilfe. Grüße.

+0

Nicht relevant, aber die Benennung eines Fragments "ProfileTeacherActivity" ist ein bisschen irreführend. :) –

+0

@TalhaMir Ja, das ist mein dummer Fehler. ;) –

Antwort

1

Betrachten EventBus zum Beispiel unter Verwendung Otto

Die Nutzung ist sehr einfach. Alles, was Sie tun müssen, ist eine evenbus erstellen:

public static Bus bus = new Bus(ThreadEnforcer.MAIN); //use Dagger2 to avoid static 

Dann eine Empfänger-Methode (2 in Ihrem Fall in Fragmente) erstellen:

@Subscribe 
public void getMessage(String s) { 
    Toast.makeText(this, s, Toast.LENGTH_LONG).show(); 
} 

Senden Ihnen Nachricht von (von DialigFramgent) Aufruf:

bus.post("Hello"); 

Und vergessen Sie nicht Ihre EventBus innerhalb onCreate Methode (Ihres Fragment) zu registrieren:

bus.register(this); 

Und das ist!

+0

Wirklich, versuche gerade .. –

+0

Wenn ich 'bus.post (" Hallo ");' innerhalb des Erfolgsrückrufs nenne, löst das Ereignis des Teilnehmers nie aus. Es löst aus, wenn ich den Callback von außerhalb des Erfolgs anrufe. –

+0

Danke dafür, sehen Sie meine Antwort unten .. –

1

Dies ist ein Beispielcode DialogFragment, der zum Senden der Nachricht an den ausgewählten Kontakt verwendet wird. Ich habe auch das Click-Ereignis auf dem DialogFragment und Redirect erfassen müssen.

Idealer dies zu erreichen, ist es das, was

  • Aufschalten die positive/negative Tastenklicks von AlertDialog.Builder und tun
  • Nachdem dies keine Aktion getan werden musste, getButton Verfahren erwähnen AlertDialog.BUTTON_NEGATIVE oder AlertDialog.BUTTON_POSITIVE verwenden und ordnen eine Aktion

public class SMSDialogFrag extends DialogFragment { 

    private static String one="one"; 
    private EditText messageContent; 
    private AlertDialog dialog; 
    private String mobNumber; 

    public static SMSDialogFrag showDialog(String mobNumber){ 
     SMSDialogFrag customDialogFrag=new SMSDialogFrag(); 
     Bundle bundle=new Bundle(); 
     bundle.putString(one, mobNumber); 
     customDialogFrag.setArguments(bundle); 
     return customDialogFrag; 
    } 

    @Override 
    public Dialog onCreateDialog(Bundle savedInstanceState) { 

     AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity()); 
     View view = getActivity().getLayoutInflater().inflate(R.layout.sms_dialog, null); 

     alertDialogBuilder.setView(view); 
     setupUI(view); 
     alertDialogBuilder.setTitle(""); 

     alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       //Do nothing here because we override this button later 
      } 
     }); 
     alertDialogBuilder.setPositiveButton("Send", new DialogInterface.OnClickListener() { 
      @Override 
      public void onClick(DialogInterface dialog, int which) { 
       //Do nothing here because we override this button later 
      } 
     }); 
     dialog = alertDialogBuilder.create(); 
     dialog.show(); 
     dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       dialog.dismiss(); 
       //else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false. 
      } 
     }); 
     dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       sendMessage();//IN YOUR USE CASE YOU CAN REDIRECT TO YOUR CALLER FRAGMENT 

      } 
     }); 

     return dialog; 
    } 
    void setupUI(View view){ 
     TextView textViewMob=(TextView)view.findViewById(R.id.mobNumber); 
     messageContent=(EditText)view.findViewById(R.id.messageContent); 
     mobNumber=getArguments().getString(one); 
     textViewMob.setText("Send message to : "+mobNumber); 
    } 
    void sendMessage(){ 
     if(! TextUtils.isEmpty(messageContent.getText())){ 
      try { 
       SmsManager smsManager = SmsManager.getDefault(); 
       Log.v(Constants.UI_LOG,"Number >>>>>>> "+mobNumber); 
       smsManager.sendTextMessage(mobNumber, null, messageContent.getText().toString(), null, null); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      Toast.makeText(getActivity(),"Message Sent!",Toast.LENGTH_SHORT).show(); 
      dialog.dismiss(); 
     }else{ 
      Toast.makeText(getActivity(),"Please enter message to send!",Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 
+0

Schöne Lösungen Mate, aber gibt es irgendwelche fehlerhaft oder falsch verwendet, wenn wir die Standardaktion von beiden 'OK' und' Cancel' ersetzen? –

+0

@NorlihazmeyGhazali: Ich habe keine gefunden. Wahrscheinlich können Sie versuchen, zu implementieren und zu überprüfen – Stallion

+0

In Ordnung, trotzdem danke Kumpel. versuchen Sie es jetzt .. –

1

Aus architektonischer Sicht sollten 2 Fragmente nicht direkt miteinander kommunizieren. Die Containeraktivität sollte für die Übergabe von Daten zwischen den untergeordneten Fragmenten verantwortlich sein. So, hier ist, wie ich es tun würde:

Implementieren Sie Ihre Schnittstelle in der Container-Aktivität und nur Ihre Schnittstellenimplementierung in der Aktivität an die Dialog-Klasse anhängen und diese Schnittstelle Methode aufrufen, wenn erforderlich. Etwas wie folgt aus:

public static class ModalBox extends DialogFragment { 

    EditProfileModalBoxInterface mListener; 

    // Container Activity must implement this interface 
    public interface EditProfileModalBoxInterface { 
    void onFinishEditProfile(HashMap<String, String> dataPassing); 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     try { 
      mListener = (EditProfileModalBoxInterface) activity; 
     } catch (ClassCastException e) { 
      throw new ClassCastException(activity.toString() + " must implement EditProfileModalBoxInterface"); 
     } 
    } 
} 

Dann mListener.onFinishEditProfile(....) nennen, wo immer es in der DialogFragment Klasse erforderlich ist.

Auf diese Weise erhalten Sie das Ergebnis zurück in Ihrer Activity Klasse, von wo Sie die relevante Methode des gewünschten Fragments aufrufen können, um die Ergebnisse an dieses Fragment zu übergeben.

Diese ganze Strömung hat here

+0

Sieht aus wie ich bin das falsche Konzept im Moment verwenden, indem ich zwei Fragmente miteinander kommunizieren. Also, auch ich benutze 'eventBus' wie der andere Typ ist Antwort, ist es nicht gültig oder nicht empfohlen? –

+0

@NorlihazmeyGhazali Otto wird auch arbeiten. Ich benutze es die ganze Zeit. Es ist eine handliche Bibliothek. Ich wollte nur erklären, wie Google es offiziell empfiehlt. Aber die Verwendung von EventBus ist auch für dieses Problem eine vollständige Lösung. –

+0

Danke für die Klarstellung. Ich kommuniziere zwischen zwei Fragmenten direkt, weil ich vermeiden möchte, mit der Hauptaktivität herumzuspielen, weil ich andere Fragmente habe, mit denen ich mich befassen muss. Wie auch immer, dieser Weg funktioniert, wenn ich das 'mlistener.onFinishEditProfile (....) 'außerhalb des asynchronen Erfolgs Callbacks von Retrofit anrufe, funktionierte leider nicht, wenn ich drinnen anrief. So seltsam. –

0

schließlich der Täter gründet beschrieben. Alle oben genannten Antworten waren richtig. Und mein Skript funktioniert auch tatsächlich, das Problem hängt mit meiner API json's Antwort zusammen, die nicht mit der richtigen Struktur kam. In meinem Fall benutze ich retrofit2 mit GSON Konverter zum Parsen in .Fand die Informationen über log sagen über sich selbst:

Erwartet BEGIN_OBJECT aber war BEGIN_ARRAY

bedeutet, dass GSON die json object erwartet, das ist mein API JSON array zurückgegeben wurde. Ändern Sie einfach die API-Struktur und dann alle Waren. Danke Jungs für Ihre harte Zeit. Wirklich geschätzt, da ich gerade jetzt weiß, wie man mit umgeht, Standard OK und Cancel Knopf und den korrekten Weg für die Kommunikation zwischen Fragmenten zu ersetzen.

+0

yep, immer Ihre Nachrüstung anmelden. Vergiss nicht Dagger2 zu benutzen. Erwägen Sie auch die Verwendung von RxJava mit Nachrüstung. Beste. –

Verwandte Themen