更新:找到答案。解决了这个问题。
这不是一个重复的问题。
,我无法找到哪个textView正在变为null。请告诉我哪些文字视图未初始化?
错误消息是
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.pronoy.mukhe.todoapplication, PID: 11245 java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.TextView.setText(java.lang.CharSequence中)'在null 对象参考 在android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:392) 在android.widget.ArrayAdapter.getView(ArrayAdapter.java:362) 在android.widget.AbsSpinner.onMeasure(AbsSpinner.java:197) 在android.widget.Spinner.onMeasure(Spinner.java:507) 在android.support.v7.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:426) 在android.view.View.measure(View.java:17429) 在android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1210) 在android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:1550) 在android.view.View.measure(View.java:17429) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:430) 在android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139) 在android.view.View.measure(View.java:17429) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 在android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) 在android.widget.LinearLayout.measureVertical(LinearLayout.java:722) 在android.widget.LinearLayout.onMeasure(LinearLayout.java:613) 在android.view.View.measure(View.java:17429) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:430) 在android.view.View.measure(View.java:17429) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 在android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) 在android.widget.LinearLayout.measureVertical(LinearLayout.java:722) 在android.widget.LinearLayout.onMeasure(LinearLayout.java:613) 在android.view.View.measure(View.java:17429) 在android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 在android.widget.FrameLayout.onMeasure(FrameLayout.java:430) 在com.android.internal.policy.impl.PhoneWindow $ DecorView.onMeasure(PhoneWindow.java:2815) 在android.view.View.measure(View.java:17429) 在android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001) 在android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1141) 在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372) 在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054) 在android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:5786) 在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:767) 在android.view.Choreographer.doCallbacks(Choreographer.java:580) 在android.view.Choreographer.doFrame(Choreographer.java:550) 在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:753) 在android.os.Handler.handleCallback(Handler.java:739) 在android.os.Handler.dispatchMessage(Handler.java:95) 在android.os.Looper.loop(Looper.java:135) 在android.app.ActivityThread.main(ActivityThread.java:5256) at java.lang.reflect.Method.invoke(Native Method) 在java.lang.reflect.Method.invoke(Method.java:372) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:898) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
public class AddTodoDialog extends AppCompatActivity {
private static final String TAG_CLASS = AddTodoDialog.class.getSimpleName();
AppCompatEditText _title, _desc;
AppCompatTextView _date, _time;
AppCompatCheckBox _isReminder;
AppCompatSpinner _category, _priority;
AppCompatButton _saveButton, _discardButton;
ConstraintLayout _pickerLayout;
String priority, category;
boolean isDateSelected, isTimeSelected = false;
ArrayList<String> categoryList = new ArrayList<>();
ArrayList<String> priorityList = new ArrayList<>();
int yearSelected, monthSelected, daySelected, hourSelected, minuteSelected;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_todo_dialog);
initializeViews();
_pickerLayout.setVisibility(View.GONE);
addCategoryToList();
addPriorityToList();
setAdapters();
_isReminder.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (compoundButton.isChecked()) {
_pickerLayout.setVisibility(View.VISIBLE);
} else _pickerLayout.setVisibility(View.GONE);
}
});
_priority.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (i > 0) {
priority = adapterView.getItemAtPosition(i).toString();
Messages.snackbar(view, "Priority Selected: " + priority, "");
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
Messages.toastMessage(getApplicationContext(), "Please select a Priority.", "");
}
});
_category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
if (i > 0) {
category = adapterView.getItemAtPosition(i).toString();
Messages.snackbar(view, "Category selected: " + category, "");
}
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
Messages.toastMessage(getApplicationContext(), "Please select a Priority.", "");
}
});
final DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker datePicker, int year, int monthOfYear, int dayOfMonth) {
isDateSelected = true;
yearSelected = year;
monthSelected = monthOfYear;
daySelected = dayOfMonth;
isDateSelected = true;
_date.setText(String.valueOf(dayOfMonth + "-" + monthOfYear + "-" + year));
}
};
_date.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Calendar calendar = Calendar.getInstance();
new DatePickerDialog(AddTodoDialog.this, dateSetListener,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
}
});
final TimePickerDialog.OnTimeSetListener timeSetListener = new
TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker timePicker, int hour, int minute) {
isTimeSelected = true;
hourSelected = hour;
minuteSelected = minute;
_time.setText(String.valueOf(hour + ":" + minute));
}
};
_time.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Calendar calendar = Calendar.getInstance();
new TimePickerDialog(AddTodoDialog.this, timeSetListener,
calendar.get(Calendar.HOUR),
calendar.get(Calendar.MINUTE), true);
}
});
_saveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (_isReminder.isChecked()) {
if (!_date.getText().toString().equalsIgnoreCase("") &&
!_time.getText().toString().equalsIgnoreCase("") &&
!category.equalsIgnoreCase("") &&
!priority.equalsIgnoreCase("")) {
saveReminder(true);
} else {
Messages.toastMessage(getApplicationContext(),
"Please select a date and time.", "");
}
} else if (!category.equalsIgnoreCase("") &&
!priority.equalsIgnoreCase("")) {
saveReminder(false);
} else {
Messages.toastMessage(getApplicationContext(),
"Please select all the fields.", "");
}
}
});
_discardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finishActivity(false);
}
});
}
private void initializeViews() {
_title = findViewById(R.id.todoTitleEnter);
_desc = findViewById(R.id.todoDescEnter);
_isReminder = findViewById(R.id.isReminder);
_date = findViewById(R.id.date);
_time = findViewById(R.id.time);
_category = findViewById(R.id.categoryEnter);
_priority = findViewById(R.id.priorityEnter);
_saveButton = findViewById(R.id.saveButton);
_discardButton = findViewById(R.id.discardButton);
_pickerLayout = findViewById(R.id.showPicker);
}
/**
* This is the method to set all the categories to the Array List.
*/
private void addCategoryToList() {
JSONArray categories = Constants.databaseController.getAllCategories();
categoryList.add("Categories:");//Add the heading.
try {
for (int i = 0; i < categories.length(); i++) {
JSONObject category = categories.getJSONObject(i);
categoryList.add(category.getString(Constants.CATEGORY_TABLE_DESC));
}
} catch (JSONException e) {
Messages.logMessage(TAG_CLASS, e.toString());
}
}
/**
* This is the method to add the Priority to the list.
*/
private void addPriorityToList() {
priorityList.add("Priority:");//Adding the first heading.
for (int i = 0; i < 5; i++) {
priorityList.add(String.valueOf(i + 1));
}
}
/**
* Method to set the adapters for the spinners.
*/
private void setAdapters() {
ArrayAdapter<String> categoryAdapter = new ArrayAdapter<String>(this,
R.layout.spinner_item, R.id.categoryEnter, categoryList) {
@Override
public boolean isEnabled(int position) {
if (position == 0)
return false;
return true;
}
@Override
public View getDropDownView(int position, @Nullable View convertView,
@NonNull ViewGroup parent) {
View view1 = getDropDownView(position, convertView, parent);
AppCompatTextView textView = (AppCompatTextView) view1;
if (position == 0)
textView.setTextColor(Color.GRAY);
else
textView.setTextColor(Color.BLACK);
return view1;
}
};
categoryAdapter.setDropDownViewResource(R.layout.spinner_item);
_category.setAdapter(categoryAdapter);
ArrayAdapter<String> priorityAdapter = new ArrayAdapter<String>(this,
R.layout.spinner_item, R.id.priorityEnter, priorityList) {
@Override
public boolean isEnabled(int position) {
if (position == 0)
return false;
return true;
}
@Override
public View getDropDownView(int position, @Nullable View convertView,
@NonNull ViewGroup parent) {
View view = getDropDownView(position, convertView, parent);
AppCompatTextView textView = (AppCompatTextView) view;
if (position == 0)
textView.setTextColor(Color.GRAY);
else
textView.setTextColor(Color.BLACK);
return view;
}
};
priorityAdapter.setDropDownViewResource(R.layout.spinner_item);
_priority.setAdapter(priorityAdapter);
}
/**
* Method to insert data to Database and save the reminder.
*
* @param isReminder: true, if there will be a notification, else false.
*/
private void saveReminder(boolean isReminder) {
try {
String title = _title.getText().toString();
String desc = _desc.getText().toString();
int categoryId = Constants.databaseController.getCategoryID(category)
.getInt(Constants.CATEGORY_TABLE_ID);
ContentValues values = new ContentValues();
values.put(Constants.TODO_TABLE_TITLE, title);
values.put(Constants.TODO_TABLE_DESC, desc);
values.put(Constants.TODO_TABLE_PRIOROTY, Integer.valueOf(priority));
values.put(Constants.TODO_TABLE_CATEGORYID, categoryId);
if (isReminder) {
Calendar calendar = Calendar.getInstance();
calendar.set(yearSelected, monthSelected, daySelected, hourSelected, minuteSelected);
long reminderTime = calendar.getTimeInMillis();
values.put(Constants.TODO_TABLE_TIME_MILIS, reminderTime);
} else {
values.put(Constants.TODO_TABLE_TIME_MILIS, 0);
}
if (Constants.databaseController.insertDataTodo(values) < 0) {
Messages.toastMessage(getApplicationContext(), "Couldn't save Reminder.", "");
finishActivity(false);
return;
}
Messages.toastMessage(getApplicationContext(), "Reminder saved.", "");
finishActivity(true);
} catch (NullPointerException | JSONException e) {
Messages.logMessage(TAG_CLASS, e.toString());
Messages.toastMessage(getApplicationContext(), "Couldn't save Reminder.", "");
finishActivity(false);
}
}
/**
* Method to complete and close the dialog.
*
* @param isReminderSet: TRUE, if the reminder is set by the user, else false.
*/
private void finishActivity(boolean isReminderSet) {
Intent returnIntent = new Intent();
if (isReminderSet)
setResult(RESULT_OK, returnIntent);
else {
setResult(RESULT_CANCELED, returnIntent);
}
finish();
}
}
这是布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fcfcfc">
<android.support.v7.widget.AppCompatEditText
android:id="@+id/todoTitleEnter"
android:textColor="#000000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:hint="@string/title_todo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.AppCompatEditText
android:id="@+id/todoDescEnter"
android:textColor="#000000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:hint="@string/description_todo"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/todoTitleEnter" />
<android.support.v7.widget.AppCompatCheckBox
android:id="@+id/isReminder"
android:textColor="#000"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/add_reminder"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/todoDescEnter" />
<android.support.constraint.ConstraintLayout
android:id="@+id/showPicker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="166dp"
app:layout_constraintTop_toBottomOf="@id/isReminder"
app:layout_constraintStart_toEndOf="parent">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/date"
android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:hint="@string/select_date"
app:layout_constraintEnd_toStartOf="@+id/time"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.AppCompatTextView
android:id="@+id/time"
android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginEnd="76dp"
android:layout_marginTop="8dp"
android:hint="@string/select_time"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
<android.support.v7.widget.AppCompatSpinner
android:id="@+id/categoryEnter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="68dp"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/showPicker"/>
<android.support.v7.widget.AppCompatSpinner
android:id="@+id/priorityEnter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="56dp"
android:layout_marginStart="8dp"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.72"
app:layout_constraintStart_toEndOf="@+id/categoryEnter"
app:layout_constraintTop_toBottomOf="@+id/showPicker" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/discardButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="56dp"
android:layout_marginTop="24dp"
android:background="@drawable/circle_button"
android:text="@string/discard"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/categoryEnter"
app:layout_constraintVertical_bias="1.0" />
<android.support.v7.widget.AppCompatButton
android:id="@+id/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="28dp"
android:background="@drawable/circle_button"
android:text="@string/save_todo"
android:textColor="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.47"
app:layout_constraintStart_toEndOf="@+id/discardButton"
app:layout_constraintTop_toBottomOf="@+id/priorityEnter"
app:layout_constraintVertical_bias="0.0" />
</android.support.constraint.ConstraintLayout>
更新:找到答案。解决了这个问题。
问题是微调器Item的根元素。
旧的spinner_item布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<android.support.v7.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/spinnerItem"
android:fontFamily="sans-serif-condensed"
tools:text="Household"
android:textStyle="bold"
android:textSize="18sp"
android:textAlignment="center"/>
</android.support.constraint.ConstraintLayout>
新的微调器项目布局。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.AppCompatTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/spinnerItem"
android:fontFamily="sans-serif-smallcaps"
tools:text="Household"
android:gravity="center"
android:padding="15dp"
android:textSize="20sp"
android:textColor="#000"
android:textStyle="bold"/>
答案 0 :(得分:0)
微调器项的根元素不应该是只应包含窗口小部件的布局。