You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用OnDismissListener致Android App崩溃,求对话框关闭执行代码方案

问题分析与解决方案

你的App崩溃根源很明确:在调用datefragment.show()后立刻执行datefragment.getDialog()时,Dialog还未完成初始化,返回了null,导致调用setOnDismissListener触发空指针异常。

下面给你几种更规范、更健壮的实现方式,来处理对话框关闭后的回调逻辑:


方案1:使用接口回调(Fragment与Activity通信的经典方式)

这种方式能让DialogFragment和Activity解耦,同时确保回调逻辑可靠。

第一步:在DatePickerFragment中定义回调接口

public class DatePickerFragment extends DialogFragment {
    // 定义回调接口,用于通知Activity对话框关闭事件
    public interface OnDialogDismissListener {
        void onDialogDismissed();
        // 可选:如果需要传递选中的日期数据,可以扩展方法
        // void onDateSelected(int year, int month, int day);
    }

    private OnDialogDismissListener mCallback;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        // 强制要求宿主Activity实现回调接口
        try {
            mCallback = (OnDialogDismissListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString() + " 必须实现OnDialogDismissListener接口");
        }
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // 初始化你的日期选择对话框
        DatePickerDialog dialog = new DatePickerDialog(
                getActivity(),
                // 这里是日期选择完成的回调(可选)
                (view, year, month, dayOfMonth) -> {
                    // 可以在这里保存选中的日期,或者直接通过回调传递给Activity
                    // mCallback.onDateSelected(year, month, dayOfMonth);
                },
                2024, 5, 21);

        // 设置对话框关闭监听
        dialog.setOnDismissListener(dialogInterface -> {
            if (mCallback != null) {
                mCallback.onDialogDismissed();
            }
        });

        return dialog;
    }
}

第二步:让Activity实现回调接口

public class AddReminder extends AppCompatActivity implements DatePickerFragment.OnDialogDismissListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_reminder);
        // ...其他初始化代码
    }

    public void onDateClick(View view) {
        loadMap();
        DialogFragment dateFragment = new DatePickerFragment();
        dateFragment.show(getFragmentManager(), "DatePicker");
        // 这里不需要再调用getDialog()了!
    }

    // 实现回调方法,对话框关闭时自动触发
    @Override
    public void onDialogDismissed() {
        updateText();
    }

    public void updateText(){
        TextView date = findViewById(R.id.tv_date);
        String text = AddReminder.monthmap.get(DatePickerFragment.month)+" "+DatePickerFragment.day+", "+DatePickerFragment.year;
        date.setText(text);
        
        TextView time = findViewById(R.id.tv_time);
        String tvdate = TimePickerFragment.hour + ":" + TimePickerFragment.min;
        time.setText(tvdate);
    }
}

方案2:使用AndroidX的FragmentResultListener(现代推荐方式)

如果你的项目使用AndroidX,可以用这种更简洁的方式传递回调事件:

第一步:在DatePickerFragment中设置结果

public class DatePickerFragment extends DialogFragment {
    public static final String DATE_DIALOG_DISMISS_KEY = "date_dialog_dismiss";

    @Override
    public void onDismiss(@NonNull DialogInterface dialog) {
        super.onDismiss(dialog);
        // 发送对话框关闭的结果通知
        getParentFragmentManager().setFragmentResult(DATE_DIALOG_DISMISS_KEY, new Bundle());
    }

    // ...你的日期选择对话框初始化代码
}

第二步:在Activity中注册监听

public class AddReminder extends AppCompatActivity {

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

        // 注册对话框关闭的结果监听
        getSupportFragmentManager().setFragmentResultListener(
                DatePickerFragment.DATE_DIALOG_DISMISS_KEY,
                this,
                (requestKey, result) -> {
                    // 对话框关闭时执行更新逻辑
                    updateText();
                });
    }

    // ...onDateClick和updateText方法保持不变
}

额外建议

你当前通过静态变量DatePickerFragment.month等传递数据的方式并不推荐,容易引发内存泄漏或数据不一致问题。建议通过上述回调接口直接传递选中的日期数据,比如修改回调方法为void onDateSelected(int year, int month, int day),在日期选择完成时把数据传递给Activity,这样代码会更健壮。

内容的提问来源于stack exchange,提问作者zbot473

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:08:12