NullPointerException setSelection spinner в Android - PullRequest
0 голосов
/ 28 октября 2019

Если пользователь выбрал книгу «Гамлет» ранее, в новом редакторе я хочу, чтобы спиннер уже был выбран в «Гамлете», и затем он может изменить это, если захочет, но я получаю это сообщение об ошибке:

NullPointerException Попытка вызвать ArrayAdapter.getPosition для нулевой ссылки на объект

В приведенном ниже коде retrieveAndSetData () должна получить выбранную книгу в базе данных для отображения на счетчике иprepareListOfBooks () должен заполнить один и тот же счетчик всеми книгами текущего пользователя для действия обновления

шаг 1

 private void retrieveAndSetData(Library l){

    library = l;

    prepareListOfBooks();

    String bookValue = library.getBookId();
    ArrayAdapter bookAdapt;
    int bookSpinnerPosition;

    bookAdapt = (ArrayAdapter) bookListSpinner.getAdapter();
    bookSpinnerPosition = bookAdapt.getPosition(bookValue);
    bookListSpinner.setSelection(bookSpinnerPosition);

}

шаг 2

private void prepareListOfBooks(){
    database = FirebaseDatabase.getInstance().getReference("books");
    account = GoogleSignIn.getLastSignedInAccount(this);
    firebaseUser = account.getId();
    query = database.orderByChild("ownerId").equalTo(firebaseUser);

    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            final List<String> books = new ArrayList<String>();

            for (DataSnapshot bookSnapshot: dataSnapshot.getChildren()) {
                String bookName = bookSnapshot.child("name").getValue(String.class);
                books.add(bookName);
            }

            Spinner bookSpinner = (Spinner) findViewById(R.id.bookListSpinner);
            ArrayAdapter<String> booksAdapter = new ArrayAdapter<String>(EditBookActivity.this, android.R.layout.simple_spinner_item, books);
            booksAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            bookSpinner.setAdapter(booksAdapter);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

Пожалуйста, что не такс моим кодом?

РЕДАКТИРОВАТЬ 1

Я изменил свой код, но все еще получаю ту же ошибку. Вот что я изменил и некоторые другие детали, которые я не показывал раньше:

public class EditBookActivity extends AppCompatActivity {
    Spinner bookListSpinner;
}



protected void onCreate(Bundle savedInstanceState) {
      ....
      prepareListOfBooks();
       ...
      bookListSpinner = (Spinner) findViewById(R.id.bookListSpinner);
}

private void prepareListOfBooks(){
    database = FirebaseDatabase.getInstance().getReference("books");
    account = GoogleSignIn.getLastSignedInAccount(this);
    firebaseUser = account.getId();
    query = database.orderByChild("ownerId").equalTo(firebaseUser);

    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            final List<String> books = new ArrayList<String>();

            for (DataSnapshot bookSnapshot: dataSnapshot.getChildren()) {
                String bookName = bookSnapshot.child("name").getValue(String.class);
                books.add(bookName);
            }

            ArrayAdapter<String> booksAdapter = new ArrayAdapter<String>(EditBookActivity.this, android.R.layout.simple_spinner_item, books);
            booksAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            //changed the line bellow, i dont create a new spinner variable, i use the same variable that is declared in the begining of this class
            bookListSpinner.setAdapter(booksAdapter); 
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

 private void retrieveAndSetData(Library l){
        library = l;

        String bookValue = library.getBookName();
        ArrayAdapter bookAdapt;
        int bookSpinnerPosition;

        bookAdapt = (ArrayAdapter) bookListSpinner.getAdapter(); //null pointer is here
        bookSpinnerPosition = bookAdapt.getPosition(bookValue);
        bookListSpinner.setSelection(bookSpinnerPosition);
}

Ответы [ 4 ]

1 голос
/ 29 октября 2019

Строка, которая вызывает ошибку: bookSpinnerPosition = bookAdapt.getPosition (bookValue);

Это означает, что bookAdapt равно null. Вы инициализируете его с помощью bookAdapt = (ArrayAdapter) bookListSpinner.getAdapter();, поэтому, скорее всего, вы неправильно установили адаптер на bookListSpinner.

Код, который вы вставили сюда, не показывает, где вы объявляете и инициализируете bookListSpinner, а также где вы создаетеадаптер для установки на него. Однако в вашем обработчике onDataChange() есть:

Spinner bookSpinner = (Spinner) findViewById(R.id.bookListSpinner);
ArrayAdapter<String> booksAdapter = new ArrayAdapter<String>(EditBookActivity.this, android.R.layout.simple_spinner_item, books);

. Он получает виджет счетчика из макета и создает для него новый адаптер каждый раз, когда запускается событие onDataChange() . ,Установка адаптера для этой локально объявленной ссылки счетчика не влияет на любые другие ссылки, которые вы объявили в другом месте.

Кроме того, создание нового адаптера для каждого события может привести к проблемам с производительностью, поскольку он перестраивает все представления. для прядильщика каждый раз. Вместо этого вы должны создать адаптер один раз в onCreate() для действия (или onCreateView(), если у вас есть фрагмент). Затем вы обновляете только данные для адаптера, а не каждый раз создаете совершенно новый адаптер.

Использование этого метода также гарантирует, что у вас есть правильный объект счетчика, доступный с правильным адаптером. На самом деле, вы можете просто сохранить ссылку на адаптер, чтобы вам вообще не нужно было звонить getAdapter().

1 голос
/ 29 октября 2019

Ваш bookValue или bookId находится вне диапазона. может быть, вы хотите использовать его как индекс, но идентификатор находится вне диапазона списка

0 голосов
/ 29 октября 2019

Проблема была связана с тем, как Firebase асинхронно обрабатывал мои данные. Когда я пытался получить доступ к ArrayAdapter на

 bookAdapt = (ArrayAdapter) bookListSpinner.getAdapter();

, я получал нулевой указатель, потому что ArrayAdapter еще не был готов. Чтобы решить, я следовал этому решению :

0 голосов
/ 29 октября 2019

Прежде всего вы передаете строку для позиции, которая должна быть целым числом

 String bookValue = library.getBookId();
 bookSpinnerPosition = bookAdapt.getPosition(bookValue);

, а затем вы используете это значение в качестве позиции, вы уверены, что идентификаторы в порядке, а небольше, чем размер-1?

...