TextView NULL指针异常

时间:2018-04-29 14:30:09

标签: java android android-layout spinner android-arrayadapter

  

更新:找到答案。解决了这个问题。

这不是一个重复的问题。

,我无法找到哪个textView正在变为null。

请告诉我哪些文字视图未初始化?

The layout is simple:

错误消息是

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"/>

1 个答案:

答案 0 :(得分:0)

微调器项的根元素不应该是只应包含窗口小部件的布局。