[英]NullPointerException setSelection spinner in Android
如果用戶之前選擇了“哈姆雷特”一書,在新的編輯活動中,我希望已經在“哈姆雷特”處選擇了微調器,然后他們可以根據需要更改此設置,但我收到此錯誤消息:
NullPointerException 嘗試在 null object 參考上調用 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);
}
您的 bookValue 或 bookId 超出范圍。 也許您想像索引一樣使用它,但 id 不在列表范圍內
導致錯誤的行: 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 onCreateView()
) 中創建)。 然后您只需更新適配器的數據,而不是每次都創建一個全新的適配器。
使用此技術還可以確保您擁有正確的微調器 object 以及正確的適配器。 實際上,您可以只保留對適配器的引用,因此您根本不需要調用getAdapter()
。
首先,您要傳遞 position 的字符串,它應該是 integer
String bookValue = library.getBookId();
bookSpinnerPosition = bookAdapt.getPosition(bookValue);
然后您將此值用作 position,您確定 id 是有序的並且不大於 size-1 嗎?
問題與 Firebase 如何異步處理我的數據有關。 當我試圖訪問 ArrayAdapter 時
bookAdapt = (ArrayAdapter) bookListSpinner.getAdapter();
我收到了一個 null 指針,因為 ArrayAdapter 還沒有准備好。 為了解決,我遵循了這個解決方案:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.