数组适配在填充 listView 时给出空指针异常
Array Adaption giving null pointer Exception while populating listView
Bank.java 文件代码
package com.example.bloodbank;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class Bank extends AppCompatActivity {
private Spinner spBloodGroup,spCity;
private String bgArray[]=new String[] {"A+","A-","B+","B-","O+","O-","AB+","AB-"};
private DBConnection db;
private ListView lvDonors;
private ArrayList<String> city,name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acitvity_bank);
//Initialisation spinner
spBloodGroup=findViewById(R.id.spBloodGroup);
spCity=findViewById(R.id.spCity);
//Initialisation ListView
lvDonors=findViewById(R.id.lvDonors);
//ArrayAdapter to spinner blood group
ArrayAdapter<String> adapter =new ArrayAdapter<>(this,R.layout.bank_spinner,bgArray);
spBloodGroup.setAdapter(adapter);
//Initialisation of Arraylist
city=new ArrayList<String>();
name=new ArrayList<>();
//Initialisation of database onject
db=new DBConnection(this);
//Populating City spinner
populateList();
ArrayAdapter<String> adapter1=new ArrayAdapter<>(this,R.layout.spinner_city,city);
spCity.setAdapter(adapter1);
spBloodGroup.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
filterDonor();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
spCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
filterDonor();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
private void populateList() {
SQLiteDatabase sqldb=db.getWritableDatabase();
Cursor cursor=sqldb.rawQuery("select city from registration",null);
while(cursor.moveToNext()) {
city.add(cursor.getString(cursor.getColumnIndex("city")));
}
}
private void filterDonor() {
name.clear();
SQLiteDatabase sqldb=db.getWritableDatabase();
Cursor cursor=sqldb.rawQuery("select name from registration natural join donor where donor.bloodgroup='"+spBloodGroup.getSelectedItem().toString()+"' and registration.city='"+spCity.getSelectedItem().toString()+"'",null);
while(cursor.moveToNext()) {
name.add(cursor.getString(cursor.getColumnIndex("name")));
}
ArrayAdapter<String> adapter=new ArrayAdapter<>(this,R.layout.custom_listview,R.id.lvDonors,name);
lvDonors.setAdapter(adapter);
}
}
Custom_listview.xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp">
<TextView
android:id="@+id/lvtvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="34sp"
android:textColor="#000000"/>
</RelativeLayout>
activity_bank.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".Bank">
<TextView
android:id="@+id/tvDonarHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Donate"
android:textSize="44sp"
android:textColor="#FF0000"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/tvBLoodGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Blood Group"
android:layout_below="@+id/tvDonarHeader"
android:textSize="20sp"
android:textColor="#000000"
android:layout_marginRight="5dp"/>
<Spinner
android:id="@+id/spBloodGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/tvBLoodGroup"
android:layout_below="@+id/tvDonarHeader"/>
<TextView
android:id="@+id/tvCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="City"
android:layout_below="@+id/tvDonarHeader"
android:textSize="20sp"
android:layout_toRightOf="@+id/spBloodGroup"
android:textColor="#000000"
android:layout_marginRight="5dp"/>
<Spinner
android:id="@+id/spCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/tvCity"
android:layout_below="@+id/tvDonarHeader"/>
<ListView
android:id="@+id/lvDonors"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="@+id/spBloodGroup"
android:divider="@color/teal_200"
android:dividerHeight="2dp"
android:listSelector="@color/teal_200"/>
</RelativeLayout>
出现这个错误
E/AndroidRuntime:致命异常:main
进程:com.example.bloodbank,PID:16440
java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'void android.widget.TextView.setText(java.lang.CharSequence)'
在 android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:392)
在 android.widget.ArrayAdapter.getView(ArrayAdapter.java:362)
在 android.widget.AbsListView.obtainView(AbsListView.java:2459)
在 android.widget.ListView.measureHeightOfChildren(ListView.java:1281)
在 android.widget.ListView.onMeasure(ListView.java:1189)
在 android.view.View.measure(View.java:17765)
在 android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:841)
在 android.widget.RelativeLayout.onMeasure(RelativeLayout.java:507)
在 android.view.View.measure(View.java:17765)
在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620)
在 android.widget.FrameLayout.onMeasure(FrameLayout.java:454)
在 androidx.appcompat.widget.ContentFrameLayout.onMeasure(内容FrameLayout.java:145)
在 android.view.View.measure(View.java:17765)
在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620)
在 androidx.appcompat.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:496)
在 android.view.View.measure(View.java:17765)
在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620)
在 android.widget.FrameLayout.onMeasure(FrameLayout.java:454)
在 android.view.View.measure(View.java:17765)
在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620)
在 android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1687)
在 android.widget.LinearLayout.measureVertical(LinearLayout.java:755)
在 android.widget.LinearLayout.onMeasure(LinearLayout.java:624)
在 android.view.View.measure(View.java:17765)
在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620)
在 android.widget.FrameLayout.onMeasure(FrameLayout.java:454)
在 com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2616)
在 android.view.View.measure(View.java:17765)
在 android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2349)
在 android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1373)
在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1597)
在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1251)
在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6438)
在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:795)
在 android.view.Choreographer.doCallbacks(Choreographer.java:598)
在 android.view.Choreographer.doFrame(Choreographer.java:567)
在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:781)
在 android.os.Handler.handleCallback(Handler.java:810)
在 android.os.Handler.dispatchMessage(Handler.java:99)
在 android.os.Looper.loop(Looper.java:189)
在 android.app.ActivityThread.main(ActivityThread.java:5532)
在 java.lang.reflect.Method.invoke(本机方法)
在 java.lang.reflect.Method.invoke(Method.java:372)
在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950)
在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
在我看来,在倒数第二行,您正试图调用此构造函数:
ArrayAdapter(上下文上下文,int 资源,int textViewResourceId,T[] 对象)
请注意,第三个参数应该是对 TextView 的引用。但是你的第三个参数是对 ListView 的引用。
Bank.java 文件代码
package com.example.bloodbank;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class Bank extends AppCompatActivity {
private Spinner spBloodGroup,spCity;
private String bgArray[]=new String[] {"A+","A-","B+","B-","O+","O-","AB+","AB-"};
private DBConnection db;
private ListView lvDonors;
private ArrayList<String> city,name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acitvity_bank);
//Initialisation spinner
spBloodGroup=findViewById(R.id.spBloodGroup);
spCity=findViewById(R.id.spCity);
//Initialisation ListView
lvDonors=findViewById(R.id.lvDonors);
//ArrayAdapter to spinner blood group
ArrayAdapter<String> adapter =new ArrayAdapter<>(this,R.layout.bank_spinner,bgArray);
spBloodGroup.setAdapter(adapter);
//Initialisation of Arraylist
city=new ArrayList<String>();
name=new ArrayList<>();
//Initialisation of database onject
db=new DBConnection(this);
//Populating City spinner
populateList();
ArrayAdapter<String> adapter1=new ArrayAdapter<>(this,R.layout.spinner_city,city);
spCity.setAdapter(adapter1);
spBloodGroup.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
filterDonor();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
spCity.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
filterDonor();
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
private void populateList() {
SQLiteDatabase sqldb=db.getWritableDatabase();
Cursor cursor=sqldb.rawQuery("select city from registration",null);
while(cursor.moveToNext()) {
city.add(cursor.getString(cursor.getColumnIndex("city")));
}
}
private void filterDonor() {
name.clear();
SQLiteDatabase sqldb=db.getWritableDatabase();
Cursor cursor=sqldb.rawQuery("select name from registration natural join donor where donor.bloodgroup='"+spBloodGroup.getSelectedItem().toString()+"' and registration.city='"+spCity.getSelectedItem().toString()+"'",null);
while(cursor.moveToNext()) {
name.add(cursor.getString(cursor.getColumnIndex("name")));
}
ArrayAdapter<String> adapter=new ArrayAdapter<>(this,R.layout.custom_listview,R.id.lvDonors,name);
lvDonors.setAdapter(adapter);
}
}
Custom_listview.xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp">
<TextView
android:id="@+id/lvtvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="34sp"
android:textColor="#000000"/>
</RelativeLayout>
activity_bank.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".Bank">
<TextView
android:id="@+id/tvDonarHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Donate"
android:textSize="44sp"
android:textColor="#FF0000"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/tvBLoodGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Blood Group"
android:layout_below="@+id/tvDonarHeader"
android:textSize="20sp"
android:textColor="#000000"
android:layout_marginRight="5dp"/>
<Spinner
android:id="@+id/spBloodGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/tvBLoodGroup"
android:layout_below="@+id/tvDonarHeader"/>
<TextView
android:id="@+id/tvCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="City"
android:layout_below="@+id/tvDonarHeader"
android:textSize="20sp"
android:layout_toRightOf="@+id/spBloodGroup"
android:textColor="#000000"
android:layout_marginRight="5dp"/>
<Spinner
android:id="@+id/spCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/tvCity"
android:layout_below="@+id/tvDonarHeader"/>
<ListView
android:id="@+id/lvDonors"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="@+id/spBloodGroup"
android:divider="@color/teal_200"
android:dividerHeight="2dp"
android:listSelector="@color/teal_200"/>
</RelativeLayout>
出现这个错误
E/AndroidRuntime:致命异常:main 进程:com.example.bloodbank,PID:16440 java.lang.NullPointerException: 尝试在空对象引用上调用虚拟方法 'void android.widget.TextView.setText(java.lang.CharSequence)' 在 android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:392) 在 android.widget.ArrayAdapter.getView(ArrayAdapter.java:362) 在 android.widget.AbsListView.obtainView(AbsListView.java:2459) 在 android.widget.ListView.measureHeightOfChildren(ListView.java:1281) 在 android.widget.ListView.onMeasure(ListView.java:1189) 在 android.view.View.measure(View.java:17765) 在 android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:841) 在 android.widget.RelativeLayout.onMeasure(RelativeLayout.java:507) 在 android.view.View.measure(View.java:17765) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620) 在 android.widget.FrameLayout.onMeasure(FrameLayout.java:454) 在 androidx.appcompat.widget.ContentFrameLayout.onMeasure(内容FrameLayout.java:145) 在 android.view.View.measure(View.java:17765) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620) 在 androidx.appcompat.widget.ActionBarOverlayLayout.onMeasure(ActionBarOverlayLayout.java:496) 在 android.view.View.measure(View.java:17765) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620) 在 android.widget.FrameLayout.onMeasure(FrameLayout.java:454) 在 android.view.View.measure(View.java:17765) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620) 在 android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1687) 在 android.widget.LinearLayout.measureVertical(LinearLayout.java:755) 在 android.widget.LinearLayout.onMeasure(LinearLayout.java:624) 在 android.view.View.measure(View.java:17765) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5620) 在 android.widget.FrameLayout.onMeasure(FrameLayout.java:454) 在 com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2616) 在 android.view.View.measure(View.java:17765) 在 android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2349) 在 android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1373) 在 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1597) 在 android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1251) 在 android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6438) 在 android.view.Choreographer$CallbackRecord.run(Choreographer.java:795) 在 android.view.Choreographer.doCallbacks(Choreographer.java:598) 在 android.view.Choreographer.doFrame(Choreographer.java:567) 在 android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:781) 在 android.os.Handler.handleCallback(Handler.java:810) 在 android.os.Handler.dispatchMessage(Handler.java:99) 在 android.os.Looper.loop(Looper.java:189) 在 android.app.ActivityThread.main(ActivityThread.java:5532) 在 java.lang.reflect.Method.invoke(本机方法) 在 java.lang.reflect.Method.invoke(Method.java:372) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745)
在我看来,在倒数第二行,您正试图调用此构造函数:
ArrayAdapter(上下文上下文,int 资源,int textViewResourceId,T[] 对象)
请注意,第三个参数应该是对 TextView 的引用。但是你的第三个参数是对 ListView 的引用。