【问题标题】:How to return the results form a DatePickerFragment to a Fragment如何将结果从 DatePicker 片段返回到片段
【发布时间】:2019-07-26 03:30:58
【问题描述】:

如何将结果从 DatePicker 返回到调用它的 Fragment。

我想在调用它的 Fragment 中显示带有 DatePicker 的结果的 Toast。

public class UIFragment extends Fragment  {

    @BindView(R.id.btn_date_picker) Button btnDatePicker;

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

        Log.d(LOG_TAG, "onCreateView");

        // ButterKnife
        ButterKnife.bind(this, view);

        btnDatePicker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(LOG_TAG, "Date Picker");


                // A DialogFragment displays a dialog window floating on top of the activity window.
                DialogFragment newFragment = new DatePickerFragment();
                newFragment.show(getActivity().getSupportFragmentManager(), "datePicker");

            }
        });

        public void processDatePickerResult(int year, int month, int day) {
        Log.d(LOG_TAG, "processDatePickerResult()");

        String month_string = Integer.toString(month + 1);
        String day_string = Integer.toString(day);
        String year_string = Integer.toString(year);
        String date = (month_string + "/" + day_string + "/" + year_string);

        displayToast(date);
    }

}
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener  {
    private static final String LOG_TAG = DatePickerFragment.class.getSimpleName();

    DatePickerDialog.OnDateSetListener listener;


    @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        Log.d(LOG_TAG, "onDateSet: Year: " + year + " month: " + (month + 1) + " Day: " + dayOfMonth);

        UIFragment uiFragment = (UIFragment)getTargetFragment();
        uiFragment.processDatePickerResult(year, month, dayOfMonth);
    }


    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle saveInstanceState) {
        Log.d(LOG_TAG, "onCreateDialog");

        // Use current date as the default date in the picker.
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it.
        return new DatePickerDialog(getActivity(), this, year, month, day);

    }

}

DatePickerFragment.onDateSet方法和UIFragment.processDatePickerResult方法后APP崩溃。

我已经附上了 Log cat 的副本:

2019-07-25 21:26:18.867 14671-14671/com.example.androidui2 D/UIFragment:onCreateView 2019-07-25 21:26:24.425 14671-14671/com.example.androidui2 D/UIFragment:日期选择器 2019-07-25 21:26:24.444 14671-14671/com.example.androidui2 D/DatePickerFragment:onCreateDialog 2019-07-25 21:26:26.701 14671-14671/com.example.androidui2 D/DatePickerFragment:onDateSet: 年:2019 月:7 日:25 2019-07-25 21:26:26.705 14671-14671/com.example.androidui2 E/AndroidRuntime:致命异常: 主要的 进程:com.example.androidui2,PID:14671 java.lang.NullPointerException:尝试调用虚拟方法'void com.example.androidui2.FragmentTabs.UIFragment.processDatePickerResult(int, int, int)' 在空对象引用上 在 com.example.androidui2.Picker.DatePickerFragment.onDateSet(DatePickerFragment.java:50) 在 android.app.DatePickerDialog.onClick(DatePickerDialog.java:171) 在 com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:172) 在 android.os.Handler.dispatchMessage(Handler.java:106) 在 android.os.Looper.loop(Looper.java:193) 在 android.app.ActivityThread.main(ActivityThread.java:6669) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

【问题讨论】:

标签: android android-fragments datepicker


【解决方案1】:

试试下面的代码。

UIFragment.java

public class UIFragment extends Fragment implements DatePickerFragment.IDateSetListener  {

    @BindView(R.id.btn_date_picker) Button btnDatePicker;

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

        Log.d(LOG_TAG, "onCreateView");

        // ButterKnife
        ButterKnife.bind(this, view);
        final DialogFragment newFragment = new DatePickerFragment();
        ((DatePickerFragment)newFragment).setIDateSetListener(this);

        btnDatePicker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(LOG_TAG, "Date Picker");


                // A DialogFragment displays a dialog window floating on top of the activity window.        

              newFragment.show(getActivity().getSupportFragmentManager(), "datePicker");

            }
        });
    }

    @Override
    public void processDatePickerResult(int year, int month, int day) {

        Log.d(LOG_TAG, "processDatePickerResult()");

        String month_string = Integer.toString(month + 1);
        String day_string = Integer.toString(day);
        String year_string = Integer.toString(year);
        String date = (month_string + "/" + day_string + "/" + year_string);

        displayToast(date);
    }

}

DatePickerFragment.java

public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener  {
    private static final String LOG_TAG = DatePickerFragment.class.getSimpleName();

    IDateSetListener dateSetListener;

    public void setIDateSetListener(IDateSetListener listener) {
        dateSetListener = listener;
    }

    public interface IDateSetListener {
        void processDatePickerResult(int year, int month, int day)
    }


    @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        Log.d(LOG_TAG, "onDateSet: Year: " + year + " month: " + (month + 1) + " Day: " + dayOfMonth);
        if (dateSetListener != null) {
            dateSetListener.processDatePickerResult(year, month, dayOfMonth);
        }
    }


    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle saveInstanceState) {
        Log.d(LOG_TAG, "onCreateDialog");

        // Use current date as the default date in the picker.
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it.
        return new DatePickerDialog(getActivity(), this, year, month, day);

    }

}

【讨论】:

  • 这可行,但有些事情我不清楚。为什么 DialogFragment 必须在 onClickListner() 之外声明?日期片段中有两个警告。 1) DatePickerFragment 应该提供一个不带参数的构造函数。 2) 避免在片段中使用非默认构造函数:使用默认构造函数加上 Fragment#setArguments?.
  • 此实现使用接口在您的对话框片段和 UIFragment 之间进行通信。因此,为了将 UIFragment 的实例(实现接口 IDateSetListener)传递给 DatePickerFragment,我将 DialogFragment 移到了外部。
  • 我使用notepad++编写了代码。我现在无法访问 IDE。您可以使用 setter 方法而不是传入构造函数。我会更新答案。
  • 更新了答案。请检查。
  • 酷,这就像一个魅力,我有一些关于听众的挖掘工作,但它是我需要的。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多