Я создал диалоговое окно выбора времени в моем приложении для Android, и Android Studio продолжает показывать мне это предупреждение в коде, который "inflater.inflate может выдать нулевое исключение" .
Вот XML-файлы для пользовательского указателя времени:
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="timePickerStyle" format="reference" />
<declare-styleable name="CustomTimePicker">
<attr name="internalLayout" format="reference" />
</declare-styleable>
</resources>
time_picker_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<app.customview.CustomTimePicker xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/timePicker"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
time_picker.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layoutDirection="ltr">
<!-- hour -->
<NumberPicker
android:id="@+id/hour"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
/>
<!-- minute -->
<NumberPicker
android:id="@+id/minute"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:layout_marginStart="5dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
<!-- minute -->
<NumberPicker
android:id="@+id/amPm"
android:layout_width="70dip"
android:layout_height="wrap_content"
android:layout_marginStart="5dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
</LinearLayout>
CustomTimePickerDialog.Java
package app.customview;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TimePicker;
import app.customview.CustomTimePicker.OnTimeChangedListener;
/**
* A dialog that prompts the user for the time of day using a {@link TimePicker}.
* <p/>
* <p>See the <a href="{@docRoot}guide/topics/ui/controls/pickers.html">Pickers</a>
* guide.</p>
*/
public class CustomTimePickerDialog extends AlertDialog
implements OnClickListener, OnTimeChangedListener {
private static final String HOUR = "hour";
private static final String MINUTE = "minute";
private static final String IS_24_HOUR = "is24hour";
private final CustomTimePicker mTimePicker;
private final OnTimeSetListener mCallback;
int mInitialHourOfDay;
int mInitialMinute;
boolean mIs24HourView;
private View view;
/**
* @param context Parent.
* @param callBack How parent is notified.
* @param hourOfDay The initial hour.
* @param minute The initial minute.
* @param is24HourView Whether this is a 24 hour view, or AM/PM.
*/
public CustomTimePickerDialog(Context context,
OnTimeSetListener callBack,
int hourOfDay, int minute, boolean is24HourView) {
this(context, 0, callBack, hourOfDay, minute, is24HourView);
}
/**
* @param context Parent.
* @param theme the theme to apply to this dialog
* @param callBack How parent is notified.
* @param hourOfDay The initial hour.
* @param minute The initial minute.
* @param is24HourView Whether this is a 24 hour view, or AM/PM.
*/
public CustomTimePickerDialog(Context context,
int theme,
OnTimeSetListener callBack,
int hourOfDay, int minute, boolean is24HourView) {
super(context, theme);
mCallback = callBack;
mInitialHourOfDay = hourOfDay;
mInitialMinute = minute;
mIs24HourView = is24HourView;
setIcon(0);
// buggy
setTitle("Set Time");
//Context themeContext = getContext();
setButton(BUTTON_POSITIVE, "Done", this);
LayoutInflater inflater = getLayoutInflater();
try {
view = inflater.inflate(R.layout.time_picker_dialog, null);
} catch(android.view.InflateException e) {
view = inflater.inflate(R.layout.time_picker_dialog, null);
// do nothing
}
setView(view);
mTimePicker = (CustomTimePicker) view.findViewById(R.id.timePicker);
// initialize state
mTimePicker.setIs24HourView(mIs24HourView);
mTimePicker.setCurrentHour(mInitialHourOfDay);
mTimePicker.setCurrentMinute(mInitialMinute);
mTimePicker.setOnTimeChangedListener(this);
}
public void onClick(DialogInterface dialog, int which) {
tryNotifyTimeSet();
}
public void updateTime(int hourOfDay, int minutOfHour) {
mTimePicker.setCurrentHour(hourOfDay);
mTimePicker.setCurrentMinute(minutOfHour);
}
private void tryNotifyTimeSet() {
if (mCallback != null) {
mTimePicker.clearFocus();
mCallback.onTimeSet(mTimePicker, mTimePicker.getCurrentHour(),
mTimePicker.getCurrentMinute());
}
}
@Override
protected void onStop() {
tryNotifyTimeSet();
super.onStop();
}
@Override
public Bundle onSaveInstanceState() {
Bundle state = super.onSaveInstanceState();
state.putInt(HOUR, mTimePicker.getCurrentHour());
state.putInt(MINUTE, mTimePicker.getCurrentMinute());
state.putBoolean(IS_24_HOUR, mTimePicker.is24HourView());
return state;
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
int hour = savedInstanceState.getInt(HOUR);
int minute = savedInstanceState.getInt(MINUTE);
mTimePicker.setIs24HourView(savedInstanceState.getBoolean(IS_24_HOUR));
mTimePicker.setCurrentHour(hour);
mTimePicker.setCurrentMinute(minute);
}
@Override
public void onTimeChanged(CustomTimePicker view, int hourOfDay, int minute) {
// TODO Auto-generated method stub
}
/**
* The callback interface used to indicate the user is done filling in
* the time (they clicked on the 'Set' button).
*/
public interface OnTimeSetListener {
/**
* @param view The view associated with this listener.
* @param hourOfDay The hour that was set.
* @param minute The minute that was set.
*/
void onTimeSet(CustomTimePicker view, int hourOfDay, int minute);
}
}
CustomTimePicker.java
public CustomTimePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// initialization based on locale
setCurrentLocale(Locale.getDefault());
// process style attributes
TypedArray attributesArray = context.obtainStyledAttributes(
attrs, R.styleable.CustomTimePicker, defStyle, 0);
int layoutResourceId = attributesArray.getResourceId(
R.styleable.CustomTimePicker_internalLayout, R.layout.time_picker);
attributesArray.recycle();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(layoutResourceId, this, true);
// hour
mHourSpinner = (NumberPicker) findViewById(R.id.hour);
mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
if (!is24HourView()) {
if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY)
|| (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) {
mIsAm = !mIsAm;
updateAmPmControl();
}
}
onTimeChanged();
}
});
// minute
mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(3);
mMinuteSpinner.setDisplayedValues(new String[]{"0", "15", "30", "45"});
mMinuteSpinner.setFormatter(new TwoDigitFormatter());
mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
onTimeChanged();
}
});
/* Get the localized am/pm strings and use them in the spinner */
mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
// am/pm
View amPmView = findViewById(R.id.amPm);
if (amPmView instanceof Button) {
mAmPmSpinner = null;
mAmPmButton = (Button) amPmView;
mAmPmButton.setOnClickListener(new OnClickListener() {
public void onClick(View button) {
button.requestFocus();
mIsAm = !mIsAm;
updateAmPmControl();
onTimeChanged();
}
});
} else {
mAmPmButton = null;
mAmPmSpinner = (NumberPicker) amPmView;
mAmPmSpinner.setMinValue(0);
mAmPmSpinner.setMaxValue(1);
mAmPmSpinner.setDisplayedValues(mAmPmStrings);
mAmPmSpinner.setOnValueChangedListener(new OnValueChangeListener() {
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
picker.requestFocus();
mIsAm = !mIsAm;
updateAmPmControl();
onTimeChanged();
}
});
}
// update controls to initial state
updateHourControl();
updateAmPmControl();
setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
// set to current time
setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY));
setCurrentMinute(mTempCalendar.get(Calendar.MINUTE));
if (!isEnabled()) {
setEnabled(false);
}
}
=============================
Именно эта строка в CustomTimePickerDialog.Java, которую андроид-студия продолжает говорить «может произойти исключение java.lang.null ...», и приложение также аварийно завершает работу, если я в любом случае пытаюсь получить доступ к объекту представления, так как оно возвращает нуль , Странно, но иногда этот фрагмент кода работает нормально, и я вижу, что средство выбора времени и приложение работают нормально, но в 90% случаев код с раздуванием представления возвращает ноль, и приложение вылетает.
Может ли кто-нибудь указать, что я могу сделать, чтобы исправить это (исправить предупреждение и в конечном итоге убедиться, что инфляция представления работает).
Спасибо
ПРИМЕЧАНИЕ ДЛЯ МОДЕРАТОРОВ: Пожалуйста, не отмечайте это как дубликат, это не является общей ошибкой «нулевого исключения». Я искал несколько дней, прежде чем задавать этот вопрос, так как не могу найти ответ, который мог бы решить мою проблему.