31

我有一个创建 DatePickerDialog 的 DialogFragment。我正在使用一个调用newInstance来设置初始值的静态方法,以便使用默认的空构造函数。但是,我应该如何设置监听器?屏幕旋转后,当点击“完成”按钮时,监听器不做任何事情,因为它不存在。

public class DatePickerFragment extends DialogFragment {
    public static final String ARG_YEAR = "year";
    public static final String ARG_MONTH = "month";
    public static final String ARG_DAY = "day";

    private OnDateSetListener listener_;

    public static DatePickerFragment newInstance(OnDateSetListener listener, int year, int month, int day) {
        final DatePickerFragment date_picker = new DatePickerFragment();
        date_picker.setListener(listener);

        final Bundle arguments = new Bundle();
        arguments.putInt(ARG_YEAR, year);
        arguments.putInt(ARG_MONTH, month);
        arguments.putInt(ARG_DAY, day);
        date_picker.setArguments(arguments);

        return date_picker;
    }

    private void setListener(OnDateSetListener listener) {
        listener_ = listener;
    }

    @Override
    public Dialog onCreateDialog(Bundle saved_instance_state) {
        final Bundle arguments = getArguments();
        final int year = arguments.getInt(ARG_YEAR);
        final int month = arguments.getInt(ARG_MONTH);
        final int day = arguments.getInt(ARG_DAY);

        return new DatePickerDialog(getActivity(), listener_, year, month, day);
    }
}
4

3 回答 3

66

但是,我应该如何设置监听器?

onCreate您在以下方法中更新侦听器引用Activity

private OnDateSetListener mOds = new OnDateSetListener() {

    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear,
            int dayOfMonth) {
             // do important stuff
    }
};

并在onCreate方法中:

if (savedInstanceState != null) {
    DatePickerFragment dpf = (DatePickerFragment) getSupportFragmentManager()
            .findFragmentByTag("theTag?");
    if (dpf != null) {
        dpf.setListener(mOds);
    }
}
于 2012-12-26T18:59:30.060 回答
9

在我看来,使用 Fragment 生命周期有一种更有效的方法。您可以使用片段生命周期回调onAttach()onDetach()自动将活动转换为侦听器,如下所示:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        _listener = (OnDateSetListener)activity;
    } catch(ClassCastException e) {
        // check if _listener is null before using,
        // or throw new ClassCastException("hosting activity must implement OnDateSetListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    _listener = null;
}

此技术在此处正式记录

于 2015-01-27T09:55:27.747 回答
2

Luksprog 的答案是正确的,我只想指出,解决的关键是 findFragmentByTag() 函数。因为 Activity 也会在屏幕旋转后重新创建,所以不能调用其成员 Fragment 变量的 setter 函数,而是应该通过该函数找到旧的 Fragment 实例。

顺便说一句,标签是调用 DialogFragment.show() 时的第二个参数。

于 2015-01-01T18:37:43.993 回答