[Android / Java] Lassen Sie das Host-Fragment (Anrufer) das Ereignis von DialogFragment zurückrufen

Einführung

Ich entwickle eine App mit Android Studio (Java) Es gab eine Szene, in der ich ein Schaltflächenklickereignis in einem Dialogfeld zurückrufen und mit dem aufrufenden Fragment verarbeiten wollte. Genauer gesagt, als ich API-Kommunikation + Bildschirmübergangsverarbeitung im Dialogfeld implementiert habe, habe ich einen Rückruf implementiert, da der Bildschirmübergang wahrscheinlich nicht durchgeführt werden konnte, weil der Thread anders war. Ich habe eine Fehlermeldung wie diese erhalten: "Android IllegalStateException: Fragment nicht an Aktivität angehängt"

So konnte ich die Verarbeitung mithilfe des Rückrufs realisieren und werde schreiben, was ich damals gelernt habe.

Übersicht über die erstellte Beispiel-App

Zeigen Sie ein Fragment mit einer Schaltfläche in der Aktivität an und drücken Sie die Schaltfläche, um einen Dialog anzuzeigen. Drücken Sie im Dialogfeld auf die Schaltfläche OK, um den Text der Schaltfläche zu ändern. Nur eine einfache App

  1. Fragment anzeigen
  2. Klicken Sie auf die Schaltfläche
3. Zeigen Sie einen Dialog an 4. Klicken Sie im Dialogfeld auf die Schaltfläche OK 5. Ändern Sie die Zeichenfolge für die Schaltflächenanzeige (Rückruf und Verarbeitung mit dem aufrufenden Hostfragment).

Implementierungscode

Layoutdatei

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layout_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/fragment_sample"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

fragment_sample.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_sample"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SampleFragment">

    <Button
        android:id="@+id/bt_show_dialog"
        android:layout_width="142dp"
        android:layout_height="96dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:text="Dialoganzeige"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Java-Datei

MainActivity.java


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Fragment in Aktivität festlegen
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment_sample, new SampleFragment())
                .commit();
    }
}

** * Die Teile, die nach dem Drücken der Taste aufgerufen werden, werden in der Reihenfolge aufgelistet, in der sie aufgerufen werden **

SampleFragment.java


            //Implementiert die Implementierung der Schnittstelle
public class SampleFragment extends Fragment implements SampleDialogFragment.SampleDialogListener {

    //Definieren Sie das Schaltflächenelement der Dialoganzeige als globale Variable
    private Button button;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_sample, container, false);

        //Legen Sie den Titel in der Aktionsleiste fest
        MainActivity activity = (MainActivity) getActivity();
        activity.setTitle("Beispiel für einen Dialogrückruf");

        //Schaltflächenelemente aus dem Layout abrufen
        button = view.findViewById(R.id.bt_show_dialog);

        //Verarbeitung beim Klicken auf die Schaltfläche ・ ・ ・ ①
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Holen Sie sich Fragment Manager
                FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                //Erstellen Sie ein Instanzobjekt von SampleDialogFragment
                SampleDialogFragment dialogFragment = SampleDialogFragment.newInstance();
                //Setzen Sie das aufrufende SampleFragment-Objekt auf das SampleDialogFragment-Objekt
                dialogFragment.setTargetFragment(SampleFragment.this, 0);
                //Dialog anzeigen
                dialogFragment.show(fragmentManager, "");
            }
        });
        return view;
    }

    //Rückruf und Ausführung ... ⑤
    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        //Ändern Sie die auf der Schaltfläche angezeigten Zeichen
        button.setText("Erfolgreicher Rückruf");
    }
}

SampleDialogFragment.java


public class SampleDialogFragment extends DialogFragment {

    //Methode zum Erstellen einer Instanz
    public static SampleDialogFragment newInstance() {
        return new SampleDialogFragment();
    }

    //Implementierung einer Schnittstelle zum Empfangen von Ereignisrückrufen
    public interface SampleDialogListener {
        void onDialogPositiveClick(DialogFragment dialog);
    }

    //Definieren Sie eine Schnittstelleninstanz, die zum Signalisieren des Auslösens eines Klickereignisses verwendet wird
    private SampleDialogListener listener;

    // onAttach()Stellen Sie sicher, dass das aufrufende übergeordnete Fragment die Schnittstelle implementiert
    // onAttach():Die erste im Fragmentlebenszyklus aufgerufene Methode:
    //Wird nur einmal aufgerufen, wenn ein Fragment einer Aktivität zugeordnet ist. Der Kontext enthält die übergeordnete Aktivität ... ②
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        try {
            //Rufen Sie das aufrufende SampleFragment-Objekt ab, damit Sie Ereignisse an das übergeordnete Fragment senden können
            //Erstellen Sie eine Instanz des Listeners
            listener = (SampleDialogListener) getTargetFragment();
        } catch (ClassCastException e) {
            //Auslösen einer Ausnahme, wenn das übergeordnete Fragment die Schnittstelle nicht implementiert
            throw new ClassCastException(getTargetFragment().toString() + "Implementiert die Schnittstelle nicht");
        }
    }

    //Dialog aufCreateDialog generieren
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        //Dialog erstellen ... ③
        return new AlertDialog.Builder(getActivity())
                .setTitle("Bestätigung")
                .setMessage("Möchten Sie einen Rückruf starten?")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //Rufen Sie den Prozess zum übergeordneten Fragment zurück ... ④
                        listener.onDialogPositiveClick(SampleDialogFragment.this);
                    }
                })
                .setNegativeButton("Stornieren", null) // Stornierenボタンでは何もしないためnull
                .create();
    }
}

Schließlich

Ich habe noch nicht viel verstanden, aber ich habe viel gelernt. Ich würde mich freuen, wenn Sie Fehler kommentieren könnten.

Referenzmaterial

Es war sehr hilfreich! Vielen Dank!

Android developers Dialogfragment und Fragment-Rückrufbeziehung

Recommended Posts

[Android / Java] Lassen Sie das Host-Fragment (Anrufer) das Ereignis von DialogFragment zurückrufen
[Android] Steuern Sie das Ereignis einfach, wenn Sie in Fragment auf die Schaltfläche Zurück klicken
[Android] Rufen Sie Kotlins Standardargumentmethode von Java aus auf
Ich habe versucht, die CameraX-Bibliothek mit Android Java Fragment zu verwenden
[Android, Java] Methode zum Ermitteln des abgelaufenen Datums aus zwei Daten