[Android / Java] Faire en sorte que le fragment hôte (appelant) rappelle l'événement depuis DialogFragment

introduction

Je développe une application avec Android Studio (java) Il y avait une scène où je voulais rappeler un événement de clic de bouton dans une boîte de dialogue et le faire traiter par le fragment appelant. Pour être plus précis, lorsque j'ai implémenté le traitement de la communication API + de la transition d'écran dans la boîte de dialogue, j'ai implémenté un rappel car la transition d'écran n'a pas pu être effectuée probablement parce que le thread était différent. J'ai eu une erreur comme celle-ci `ʻAndroid IllegalStateException: fragment non attaché à l'activité``

J'ai donc pu réaliser le traitement en utilisant le callback, donc j'écrirai ce que j'ai appris à ce moment-là.

Vue d'ensemble de l'exemple d'application créé

Affichez un fragment avec un bouton dans l'activité et appuyez sur le bouton pour afficher une boîte de dialogue. Appuyez sur le bouton OK dans la boîte de dialogue pour modifier le texte du bouton. Juste une application simple

  1. Afficher le fragment
  2. Cliquez sur le bouton
3. Afficher une boîte de dialogue 4. Appuyez sur le bouton OK dans la boîte de dialogue 5. Changer la chaîne de caractères d'affichage du bouton (rappel et traitement avec le fragment hôte appelant)

Code d'implémentation

fichier de mise en page

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="Affichage de la boîte de dialogue"/>

</androidx.constraintlayout.widget.ConstraintLayout>

fichier java

MainActivity.java


public class MainActivity extends AppCompatActivity {

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

        //Définir le fragment dans l'activité
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.fragment_sample, new SampleFragment())
                .commit();
    }
}

** * Les parties appelées après avoir appuyé sur le bouton sont répertoriées dans l'ordre dans lequel elles sont appelées **

SampleFragment.java


            //Implémente pour implémenter l'interface
public class SampleFragment extends Fragment implements SampleDialogFragment.SampleDialogListener {

    //Définir l'élément bouton de l'affichage de la boîte de dialogue en tant que variable globale
    private Button button;

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

        //Définissez le titre sur la barre d'action
        MainActivity activity = (MainActivity) getActivity();
        activity.setTitle("Exemple de rappel de dialogue");

        //Obtenir des éléments de bouton à partir de la mise en page
        button = view.findViewById(R.id.bt_show_dialog);

        //Traitement lorsque le bouton est cliqué ・ ・ ・ ①
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Obtenez Fragment Manager
                FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                //Créer un objet d'instance de SampleDialogFragment
                SampleDialogFragment dialogFragment = SampleDialogFragment.newInstance();
                //Définissez l'objet SampleFragment appelant sur l'objet SampleDialogFragment
                dialogFragment.setTargetFragment(SampleFragment.this, 0);
                //Afficher la boîte de dialogue
                dialogFragment.show(fragmentManager, "");
            }
        });
        return view;
    }

    //Traitement rappelé et exécuté ... ⑤
    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        //Changer les caractères affichés sur le bouton
        button.setText("Réussite du rappel");
    }
}

SampleDialogFragment.java


public class SampleDialogFragment extends DialogFragment {

    //Méthode pour créer une instance
    public static SampleDialogFragment newInstance() {
        return new SampleDialogFragment();
    }

    //Implémentation d'une interface pour recevoir des rappels d'événements
    public interface SampleDialogListener {
        void onDialogPositiveClick(DialogFragment dialog);
    }

    //Définir une instance d'interface utilisée pour signaler le déclenchement d'un événement de clic
    private SampleDialogListener listener;

    // onAttach()Vérifiez que le fragment parent appelant implémente l'interface
    // onAttach():La première méthode appelée dans le cycle de vie du fragment,
    //Appelé une seule fois lorsqu'un fragment est associé à une activité. Le contexte contient l'activité parent ... ②
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        try {
            //Obtenez l'objet SampleFragment appelant afin que vous puissiez envoyer des événements au fragment parent
            //Créer une instance d'auditeur
            listener = (SampleDialogListener) getTargetFragment();
        } catch (ClassCastException e) {
            //Lancer une exception si le fragment parent n'implémente pas l'interface
            throw new ClassCastException(getTargetFragment().toString() + "N'implémente pas l'interface");
        }
    }

    //Générer une boîte de dialogue sur Créer un dialogue
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        //Générer une boîte de dialogue ... ③
        return new AlertDialog.Builder(getActivity())
                .setTitle("Vérification")
                .setMessage("Voulez-vous démarrer un rappel?")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //Rappelez le processus sur le fragment parent ... ④
                        listener.onDialogPositiveClick(SampleDialogFragment.this);
                    }
                })
                .setNegativeButton("Annuler", null) // Annulerボタンでは何もしないためnull
                .create();
    }
}

finalement

Je n'ai pas encore beaucoup compris, mais j'ai beaucoup appris. Je vous serais reconnaissant si vous pouviez commenter d'éventuelles erreurs.

Matériel de référence

C'était très utile! Merci beaucoup!

Android developers Fragment de dialogue et relation de rappel de fragment

Recommended Posts

[Android / Java] Faire en sorte que le fragment hôte (appelant) rappelle l'événement depuis DialogFragment
[Android] Contrôlez facilement l'événement lorsque vous appuyez sur le bouton Retour dans Fragment
[Android] Appeler la méthode d'argument par défaut de Kotlin depuis Java
J'ai essayé d'utiliser la bibliothèque CameraX avec Android Java Fragment
[Android, Java] Méthode pour trouver la date écoulée à partir de deux dates