#java #android #android-fragments #datepicker #tags
#java #Android #android-фрагменты #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);
}
}
Тем не менее, я получаю исключение NullPointerException, выполняя view.getTag(). Как я могу решить это или как еще я могу дифференцировать результаты?
Уточнение: DatePickerDialog — это собственный класс, не тот, который я создал, поэтому я не могу редактировать их методы `
TimePickerFragment:
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;
}
Ответ №1:
Решение: определите два интерфейса для пересылки данных из фрагментов в activity.
Шаг 1. Определите OnDateSetListener
интерфейс для связи между MainActivity
и DatePickerFragment
.
public interface OnDateSetListener {
void onDateSet(String tag, DatePicker view, int year, int month, int dayOfMonth);
}
Шаг 2. Определите OnTimeSetListener
интерфейс для связи между MainActivity
и TimePickerFragment
.
public interface OnTimeSetListener {
void onTimeSet(String tag, TimePicker view, int hourOfDay, int minute);
}
Шаг 3. Let 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);
}
}
Комментарии:
1. Это отлично сработало, спасибо!! Теперь я пытаюсь сделать то же самое с помощью средства выбора времени, но, поскольку TimePickerDialog не является
getTimePicker()
методом, я немного застрял там
Ответ №2:
Как я вижу, вы установили тег для фрагмента, но то, что вы пытаетесь получить, — это тег представления. Это не одно и то же, поскольку тег представления является объектом, а тег фрагмента — строкой.
Комментарии:
1. Я вижу. И как я мог бы тогда получить тег фрагмента?
2. Либо отправьте тег фрагмента вместе с onDateSet , либо установите тег представления в onViewCreated.
Ответ №3:
Как вы можете видеть, ваше представление в onDateSet — это DatePicker, и вы устанавливаете свой тег на фрагмент, содержащий DatePicker, который является DatePickerDialog.
Итак, чтобы получить свой тег, вы должны попробовать что-то вроде:
@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
if (view.getParent() != null amp;amp; 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);
}
}
Комментарии:
1. Только что попробовал это, и хотя фрагмент имеет метод getTag, в view.getParent().getTag() метод не может быть разрешен