首页 > 解决方案 > 在 DialogFragment 中附加时,Android 侦听器始终为空

问题描述

这里的高中老师试图教如何实现一个 DialogFragment 与侦听器附加一个接口到显示它的片段。由于某种原因,侦听器始终为空,当对话框显示时,当我按下对话框的确定​​或取消按钮时,向实现方法的转移不起作用,它停止了我调用侦听器类的行(始终为空)在 alertDialog.Builder 这是我的代码,谢谢

这是我调用对话框片段的片段

    package net.ccl.monapp.ui;

import android.os.Bundle;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import net.ccl.monapp.R;


public class AnimationFragment extends Fragment implements MonDialogFragment.MonDialogListener {


    public AnimationFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_animation,container,false);
        Button myButton = root.findViewById(R.id.bt_dialog);
        final TextView tvTitre = root.findViewById(R.id.tv_titre);

        myButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                DialogFragment myDialog = new MonDialogFragment();

                // Show Alert DialogFragment
                myDialog.show(getFragmentManager(), "Dialog");
            }
        });

        return root;
    }





    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        TextView myTitre = getView().findViewById(R.id.tv_titre);
        myTitre.setText("Mon nouveau titre");
        dialog.dismiss();
    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        Toast.makeText(getActivity(),"Vous avez canceler l'action du dialog",Toast.LENGTH_SHORT);
    }
}

这里是我的 DialogFragment

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;

import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;




public class MonDialogFragment extends DialogFragment {
    public MonDialogFragment() {

    }

    public interface MonDialogListener {
        void onDialogPositiveClick(DialogFragment dialog);
        void onDialogNegativeClick(DialogFragment dialog);
    }

    // Use this instance of the interface to deliver action events
    public MonDialogListener listener;



    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        try {
            // Instantiate the NoticeDialogListener so we can send events to the host
            listener = (MonDialogListener) context;
        } catch (ClassCastException e) {

        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {


        AlertDialog.Builder builder =  new AlertDialog.Builder(getActivity());

        builder.setTitle("Mon interface dialog");

        builder.setMessage("Ceci est un message qui explique que tu peux changer le titre du fragment animation en cliquant sur ok");

        builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onDialogPositiveClick(MonDialogFragment.this);

                    }
                });

        builder .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        listener.onDialogNegativeClick(MonDialogFragment.this);
                    }
                });

        return builder.create();
    }


}

这里是我的 logcat

 Process: net.ccl.monapp, PID: 13691
java.lang.NullPointerException: Attempt to invoke interface method 'void net.ccl.monapp.ui.MonDialogFragment$MonDialogListener.onDialogPositiveClick(androidx.fragment.app.DialogFragment)' on a null object reference
    at net.ccl.monapp.ui.MonDialogFragment$1.onClick(MonDialogFragment.java:56)
    at androidx.appcompat.app.AlertController$ButtonHandler.handleMessage(AlertController.java:167)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

标签: android

解决方案


onAttach()实际上并没有做任何事情,因为Context你试图投射的是你的Activity,而不是你的AnimationFragment

AnimationFragment应该通过覆盖在 Dialog 上设置侦听器,而不是伸手去接听您的听众onAttachFragment()

首先,您需要通过更改您的使用来确保您MonDialogFragment是您的子片段:AnimationFragmentshow()getChildFragmentManager()

myDialog.show(getChildFragmentManager(), "Dialog");

然后,覆盖onAttachFragment()你的AnimationFragment

@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);

    if (fragment instanceof MonDialogFragment) {
        ((MonDialogFragment) fragment).listener = this;
    }
}

然后,您可以完全onAttach()删除MonDialogFragment


推荐阅读