首页 > 解决方案 > RatingBar 错误 - 尝试在空对象引用上调用虚拟方法

问题描述

每次我尝试从我的 ratingbar 中获取评分时,我都会收到此错误:java.lang.NullPointerException: Attempt to invoke virtual method 'float android.widget.RatingBar.getRating()' on an null object reference

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.RatingBar;


public class AddEditFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

    // defines callback method implemented by MainActivity
    public interface AddEditFragmentListener {
        // called when contact is saved
        void onAddEditCompleted(Uri contactUri);
    }

    // constant used to identify the Loader
    private static final int CONTACT_LOADER = 0;

    private AddEditFragmentListener listener; // MainActivity
    private Uri contactUri; // Uri of selected contact
    private boolean addingNewContact = true; // adding (true) or editing

    // EditTexts for contact information
    private TextInputLayout titleTextInputLayout;
    private TextInputLayout yearTextInputLayout;
    private TextInputLayout directorTextInputLayout;
    private TextInputLayout writerTextInputLayout;
    private TextInputLayout producerTextInputLayout;
    private TextInputLayout actorsTextInputLayout;
    private RatingBar movieRatingBar;
    private FloatingActionButton saveContactFAB;

    private CoordinatorLayout coordinatorLayout; // used with SnackBars

    // set AddEditFragmentListener when Fragment attached
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        listener = (AddEditFragmentListener) context;
    }

    // remove AddEditFragmentListener when Fragment detached
    @Override
    public void onDetach() {
        super.onDetach();
        listener = null;
    }

    // called when Fragment's view needs to be created
    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        setHasOptionsMenu(true); // fragment has menu items to display

        // inflate GUI and get references to EditTexts
        View view = inflater.inflate(R.layout.fragment_add_edit, container, false);
        titleTextInputLayout = (TextInputLayout) view.findViewById(R.id.titleTextInputLayout);
        titleTextInputLayout.getEditText().addTextChangedListener(nameChangedListener);
        yearTextInputLayout = (TextInputLayout) view.findViewById(R.id.yearTextInputLayout);
        directorTextInputLayout = (TextInputLayout) view.findViewById(R.id.directorTextInputLayout);
        writerTextInputLayout = (TextInputLayout) view.findViewById(R.id.writerTextInputLayout);
        producerTextInputLayout = (TextInputLayout) view.findViewById(R.id.producerTextInputLayout);
        actorsTextInputLayout = (TextInputLayout) view.findViewById(R.id.actorsTextInputLayout);
        movieRatingBar = (RatingBar) view.findViewById(R.id.ratingBar);
        //zipTextInputLayout = (TextInputLayout) view.findViewById(R.id.zipTextInputLayout);

        // set FloatingActionButton's event listener
        saveContactFAB = (FloatingActionButton) view.findViewById(R.id.saveFloatingActionButton);
        saveContactFAB.setOnClickListener(saveContactButtonClicked);
        updateSaveButtonFAB();

        // used to display SnackBars with brief messages
        coordinatorLayout = (CoordinatorLayout) getActivity().findViewById(R.id.coordinatorLayout);

        Bundle arguments = getArguments(); // null if creating new contact

        if (arguments != null) {
            addingNewContact = false;
            contactUri = arguments.getParcelable(MainActivity.CONTACT_URI);
        }

        // if editing an existing contact, create Loader to get the contact
        if (contactUri != null)
            getLoaderManager().initLoader(CONTACT_LOADER, null, this);

        return view;
    }

    // detects when the text in the titleTextInputLayout's EditText changes
    // to hide or show saveButtonFAB
    private final TextWatcher nameChangedListener = new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                                      int after) {}

        // called when the text in titleTextInputLayout changes
        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                                  int count) {
            updateSaveButtonFAB();
        }

        @Override
        public void afterTextChanged(Editable s) { }
    };

    // shows saveButtonFAB only if the name is not empty
    private void updateSaveButtonFAB() {
        String input =
                titleTextInputLayout.getEditText().getText().toString();

        // if there is a name for the contact, show the FloatingActionButton
        if (input.trim().length() != 0)
            saveContactFAB.show();
        else
            saveContactFAB.hide();
    }

    // responds to event generated when user saves a contact
    private final View.OnClickListener saveContactButtonClicked =
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // hide the virtual keyboard
                    ((InputMethodManager) getActivity().getSystemService(
                            Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
                            getView().getWindowToken(), 0);
                    saveContact(); // save contact to the database
                }
            };

    // saves contact information to the database
    private void saveContact() {
        // create ContentValues object containing contact's key-value pairs
        ContentValues contentValues = new ContentValues();
        contentValues.put(Contact.COLUMN_TITLE, titleTextInputLayout.getEditText().getText().toString());
        contentValues.put(Contact.COLUMN_YEAR, yearTextInputLayout.getEditText().getText().toString());
        contentValues.put(Contact.COLUMN_DIRECTOR, directorTextInputLayout.getEditText().getText().toString());
        contentValues.put(Contact.COLUMN_WRITER, writerTextInputLayout.getEditText().getText().toString());
        contentValues.put(Contact.COLUMN_PRODUCER, producerTextInputLayout.getEditText().getText().toString());
        contentValues.put(Contact.COLUMN_ACTOR, actorsTextInputLayout.getEditText().getText().toString());
        //contentValues.put(Contact.COLUMN_RATING, zipTextInputLayout.getEditText().getText().toString());
        contentValues.put(Contact.COLUMN_RATING, movieRatingBar.getRating());

        if (addingNewContact) {
            // use Activity's ContentResolver to invoke
            // insert on the AddressBookContentProvider
            Uri newContactUri = getActivity().getContentResolver().insert(Contact.CONTENT_URI, contentValues);

            if (newContactUri != null) {
                Snackbar.make(coordinatorLayout,
                        R.string.contact_added, Snackbar.LENGTH_LONG).show();
                listener.onAddEditCompleted(newContactUri);
            }
            else {
                Snackbar.make(coordinatorLayout,
                        R.string.contact_not_added, Snackbar.LENGTH_LONG).show();
            }
        }
        else {
            // use Activity's ContentResolver to invoke
            // insert on the AddressBookContentProvider
            int updatedRows = getActivity().getContentResolver().update(
                    contactUri, contentValues, null, null);

            if (updatedRows > 0) {
                listener.onAddEditCompleted(contactUri);
                Snackbar.make(coordinatorLayout,
                        R.string.contact_updated, Snackbar.LENGTH_LONG).show();
            }
            else {
                Snackbar.make(coordinatorLayout,
                        R.string.contact_not_updated, Snackbar.LENGTH_LONG).show();
            }
        }
    }

    // called by LoaderManager to create a Loader
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // create an appropriate CursorLoader based on the id argument;
        // only one Loader in this fragment, so the switch is unnecessary
        switch (id) {
            case CONTACT_LOADER:
                return new CursorLoader(getActivity(),
                        contactUri, // Uri of contact to display
                        null, // null projection returns all columns
                        null, // null selection returns all rows
                        null, // no selection arguments
                        null); // sort order
            default:
                return null;
        }
    }

    // called by LoaderManager when loading completes
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // if the contact exists in the database, display its data
        if (data != null && data.moveToFirst()) {
            // get the column index for each data item
            int nameIndex = data.getColumnIndex(Contact.COLUMN_TITLE);
            int phoneIndex = data.getColumnIndex(Contact.COLUMN_YEAR);
            int emailIndex = data.getColumnIndex(Contact.COLUMN_DIRECTOR);
            int streetIndex = data.getColumnIndex(Contact.COLUMN_WRITER);
            int cityIndex = data.getColumnIndex(Contact.COLUMN_PRODUCER);
            int stateIndex = data.getColumnIndex(Contact.COLUMN_ACTOR);
            int rating = data.getColumnIndex(Contact.COLUMN_RATING);

            // fill EditTexts with the retrieved data
            titleTextInputLayout.getEditText().setText(data.getString(nameIndex));
            yearTextInputLayout.getEditText().setText(data.getString(phoneIndex));
            directorTextInputLayout.getEditText().setText(data.getString(emailIndex));
            writerTextInputLayout.getEditText().setText(data.getString(streetIndex));
            producerTextInputLayout.getEditText().setText(data.getString(cityIndex));
            actorsTextInputLayout.getEditText().setText(data.getString(stateIndex));
            //zipTextInputLayout.getEditText().setText(data.getString(zipIndex));
//            movieRatingBar.setRating(data.getFloat(rating));

            updateSaveButtonFAB();
        }
    }

    // called by LoaderManager when the Loader is being reset
    @Override
    public void onLoaderReset(Loader<Cursor> loader) { }
}

错误出现在 contentValues.put(Contact.COLUMN_RATING, movieRatingBar.getRating());

我也试过简单地float rating = movieRatingBar.getRating(); 它给了我同样的错误。我有 movieRatingBar = (RatingBar) view.findViewById(R.id.ratingBar); 我听说很多有这个错误的人都错过了这条线。但它仍然不起作用

这是错误

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.enzo.addressbook, PID: 4134
                  java.lang.NullPointerException: Attempt to invoke virtual method 'float android.widget.RatingBar.getRating()' on a null object reference
                      at com.enzo.movieCollection.AddEditFragment.saveContact(AddEditFragment.java:165)
                      at com.enzo.movieCollection.AddEditFragment.access$100(AddEditFragment.java:26)
                      at com.enzo.movieCollection.AddEditFragment$2.onClick(AddEditFragment.java:148)
                      at android.view.View.performClick(View.java:6294)
                      at android.view.View$PerformClick.run(View.java:24770)
                      at android.os.Handler.handleCallback(Handler.java:790)
                      at android.os.Handler.dispatchMessage(Handler.java:99)
                      at android.os.Looper.loop(Looper.java:164)
                      at android.app.ActivityThread.main(ActivityThread.java:6494)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
I/zygote: After code cache collection, code=122KB, data=86KB
          Increasing code cache capacity to 512KB
Application terminated.

标签: javaandroid

解决方案


该错误意味着在这一行中:

movieRatingBar = (RatingBar) view.findViewById(R.id.ratingBar);

RatingBar找不到视图,所以结果movieRatingBarnull
也许在 xml 中视图的 id 不是ratingBar,你拼错了吗?
或者它不间接属于那个布局?


推荐阅读