#android #android-fragments #nullpointerexception #datepicker
#Android #android-фрагменты #исключение nullpointerexception #выбор даты
Вопрос:
Я использую этот класс для отображения средства выбора даты. Это работает следующим образом
- Получение идентификатора текстового представления затем добавляет выбранную дату и время в это текстовое представление.
Когда я вызываю его из фрагментов, он работает нормально. Но когда я вызываю его из другого фрагмента диалога, он показывает средство выбора даты, а затем выдает исключение нулевого указателя при установке даты в текстовом поле. Пока фрагмент диалога все еще раздут в фоновом режиме и виден.
public class DatePickerFragment extends DialogFragment {
TextView dateTextView;
Date tempDate;
Boolean isCurrentDate;
public static DatePickerFragment newInstance(int dateTextViewId, Boolean isCurrentDate) {
DatePickerFragment fragment = new DatePickerFragment();
Bundle bundle = new Bundle();
bundle.putInt("textField", dateTextViewId);
bundle.putBoolean("flag", isCurrentDate);
fragment.setArguments(bundle);
return fragment;
}
public void setDateTextView(TextView dateTextView) {
this.dateTextView = dateTextView;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
this.dateTextView = (TextView) getActivity().findViewById(getArguments().getInt("textField"));
isCurrentDate = getArguments().getBoolean("flag");
}
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
if (isCurrentDate == false) {
year = c.get(Calendar.YEAR) - 18;
}
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH);
DatePickerDialog dialog = new DatePickerDialog(getActivity(), AlertDialog.THEME_HOLO_LIGHT, dateSetListener, year, month, day);
if (isCurrentDate)
dialog.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
else
dialog.getDatePicker().setMaxDate(c.getTimeInMillis());
return dialog;
}
private DatePickerDialog.OnDateSetListener dateSetListener =
new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int month, int day) {
DatePickerFragment.this.dateTextView.setText(view.getDayOfMonth() "/" (view.getMonth() 1) "/" view.getYear());
}
};
}
Вот как я раздуваю фрагмент диалога
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_transaction_filter_item_list, container, false)
return binding.root
}
И вот как я вызываю фрагмент средства выбора даты
val calenderFragment =
DatePickerFragment.newInstance(binding.fromDateTextView.id, false)
calenderFragment.show(activity?.supportFragmentManager!!, "")
Сообщение об ошибке
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Я не уверен, почему идентификатор не виден для действия.
Комментарии:
1. Как он работает нормально для фрагмента? вы вызываете
getActivity().findViewById
для этого представление, которое должно быть частьюActivity
notFragment
. Не рекомендуется передавать представление или идентификатор представленияDialogFragment
. Лучший способ сделать это — создать интерфейс и передать обратный вызов вызывающему компоненту с выбранной датой.2. или вы можете создать общедоступный класс в своей деятельности и вызвать его из своего дочернего фрагмента
3. @ADM Я думаю, что он отлично работает с фрагментами, потому что у меня есть одно действие, и все фрагменты прикреплены к нему.
4. Почему у вас есть общедоступный сеттер
setDateTextView
? При этом вы также вызываетеfindViewById
? Лучше использовать интерфейс, как я сказал выше в комментарии.