【问题标题】:Error getting tag from DatePickerFragment从 DatePickerFragment 获取标签时出错
【发布时间】:2019-04-09 08:50:31
【问题描述】:

我正在创建一个带有两个 DatePicker 的应用程序来设置开始日期和结束日期。由于 DatePicker 是从 DialogFragments 调用的,因此我设置了两个标签来区分主要活动中的结果:


 @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.sel_start_date:
                DialogFragment startDatePicker = new DatePickerFragment();
                startDatePicker.show(getSupportFragmentManager(), START_DATE_PICKER_TAG);
                break;
           case R.id.sel_end_date:
                DialogFragment endDatePicker = new DatePickerFragment();
                endDatePicker.show(getSupportFragmentManager(), END_DATE_PICKER_TAG);
                break;

DatePickerFragment 类:

public class DatePickerFragment extends DialogFragment {
    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener) getActivity(), year, month, day );
    }

这就是我在主要活动中获得结果的方式

  @Override
    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
        if (view.getTag().equals(START_DATE_PICKER_TAG)) {
            calendarStartDate.set(Calendar.YEAR, year);
            calendarStartDate.set(Calendar.MONTH, month);
            calendarStartDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            start_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
        } else {
            calendarEndDate.set(Calendar.YEAR, year);
            calendarEndDate.set(Calendar.MONTH, month);
            calendarEndDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
            end_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
        }
    }

但是,我在执行 view.getTag() 时遇到了 nullPointerException。我该如何解决这个问题,或者我还能如何区分结果?

声明:DatePickerDialog 是一个原生类,不是我创建的,所以我无法编辑他们的方法`

时间选择器片段:

public class TimePickerFragment extends DialogFragment {
    private static final String ARGS_TAG = "ARGS_TAG";

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);

        final String tag = getArguments().getString(ARGS_TAG);
        return new TimePickerDialog(getActivity(), (TimePickerDialog.OnTimeSetListener) getActivity(), hour, minute, android.text.format.DateFormat.is24HourFormat(getActivity())) {
                @Override
                protected void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                }
            };
    }

    public static TimePickerFragment newInstance(String tag){
        Bundle args = new Bundle();
        args.putString(ARGS_TAG, tag);
        TimePickerFragment fragment = new TimePickerFragment();
        fragment.setArguments(args);
        return fragment;
    }

【问题讨论】:

    标签: java android android-fragments datepicker tags


    【解决方案1】:

    解决方案:定义两个接口将数据从fragment转发到activity。

    第 1 步。定义OnDateSetListener接口,实现MainActivityDatePickerFragment之间的通信。

    public interface OnDateSetListener {
        void onDateSet(String tag, DatePicker view, int year, int month, int dayOfMonth);
    }
    

    第 2 步。定义OnTimeSetListener接口,实现MainActivityTimePickerFragment之间的通信。

    public interface OnTimeSetListener {
        void onTimeSet(String tag, TimePicker view, int hourOfDay, int minute);
    }
    

    第 3 步。让MainActivity 实现这两个接口。

    public class MainActivity extends AppCompatActivity implements OnDateSetListener, OnTimeSetListener {
    
        // Your code her
        ...
    
        @Override
        public void onDateSet(String tag, DatePicker view, int year, int month, int dayOfMonth) {
            // Process code with tag here
        }
    
        @Override
        public void onTimeSet(String tag, TimePicker view, int hourOfDay, int minute) {
            // Process code with tag here.
        }
    }
    

    第 4 步。更改DatePickerFragment中的代码

    public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
        private static final String ARGUMENT_TAG = "ARGUMENT_TAG";
    
        public static DatePickerFragment newInstance(String tag) {
            Bundle args = new Bundle();
            args.putString(ARGUMENT_TAG, tag);
            DatePickerFragment fragment = new DatePickerFragment();
            fragment.setArguments(args);
            return fragment;
        }
    
        @NonNull
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            Calendar calendar = Calendar.getInstance();
            int year = calendar.get(Calendar.YEAR);
            int month = calendar.get(Calendar.MONTH);
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            return new DatePickerDialog(requireActivity(), this, year, month, day);
        }
    
        @Override
        public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
            final String tag = getArguments().getString(ARGUMENT_TAG);
            OnDateSetListener listener = (OnDateSetListener) requireActivity();
            listener.onDateSet(tag, view, year, month, dayOfMonth);
        }
    }
    

    第 5 步。更改TimePickerFragment中的代码。

    public class TimePickerFragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
        private static final String ARGS_TAG = "ARGS_TAG";
    
        public static TimePickerFragment newInstance(String tag) {
            Bundle args = new Bundle();
            args.putString(ARGS_TAG, tag);
            TimePickerFragment fragment = new TimePickerFragment();
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            Calendar calendar = Calendar.getInstance();
            int hour = calendar.get(Calendar.HOUR_OF_DAY);
            int minute = calendar.get(Calendar.MINUTE);
            return new TimePickerDialog(requireActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
        }
    
    
        @Override
        public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
            final String tag = getArguments().getString(ARGS_TAG);
            OnTimeSetListener listener = (OnTimeSetListener) requireActivity();
            listener.onTimeSet(tag, view, hourOfDay, minute);
        }
    }
    

    【讨论】:

    • 这很好用,谢谢!!现在我正在尝试用时间选择器做同样的事情,但由于 TimePickerDialog 不是getTimePicker() 方法,我有点卡在那里
    【解决方案2】:

    正如我所见,您已将标签设置为 Fragment,但您想要获得的是 View 的标签。它们不是一回事,因为视图的标签是一个对象,而片段的标签是一个字符串。

    【讨论】:

    • 我明白了。那我怎么才能得到 Fragment 标签呢?
    • 要么将Fragment的标签与onDateSet一起发送,要么在onViewCreated中设置View的标签。
    【解决方案3】:

    正如您在 onDateSet 中看到的那样,您的视图是 DatePicker,并且您在包含 DatePicker 的片段上设置了标签,即 DatePickerDialog。

    因此,要获取您的标签,您应该尝试以下操作:

    @Override
        public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
            if (view.getParent() != null && view.getParent().getTag().equals(START_DATE_PICKER_TAG)) {
                calendarStartDate.set(Calendar.YEAR, year);
                calendarStartDate.set(Calendar.MONTH, month);
                calendarStartDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                start_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
            } else {
                calendarEndDate.set(Calendar.YEAR, year);
                calendarEndDate.set(Calendar.MONTH, month);
                calendarEndDate.set(Calendar.DAY_OF_MONTH, dayOfMonth);
                end_date_btn.setText(dayOfMonth + "/" + (month + 1) + "/" + year);
            }
        }
    

    【讨论】:

    • 刚试过这个,虽然fragment有getTag方法,但是在view.getParent().getTag()中方法无法解析
    猜你喜欢
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 2018-07-17
    • 1970-01-01
    相关资源
    最近更新 更多