我的应用程序使用
RecyclerView
显示可以使用 SQLite DB 添加/删除的项目列表。在应用程序的主屏幕中,RecyclerView 应显示在 2 个允许添加/删除项目的按钮上方。
当我进入 MainActivity 时,由于 RecyclerView,应用程序崩溃了,我无法确定原因。
日志显示以下错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.activities.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.ArrayList.add(java.lang.Object)' on a null object reference
at com.example.test.activities.MainActivity.displayData(MainActivity.java:73)
at com.example.test.activities.MainActivity.onCreate(MainActivity.java:42)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
这张照片显示了 RecyclerView 中没有填充任何数据的 UI(我必须注释掉代码才能加载屏幕)。
MainActivity.java:
public class MainActivity extends AppCompatActivity {
ItemDatabase db;
ArrayList<String> itemName, itemQnt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initialize DB
db = new ItemDatabase(this);
// Item variables
Button addItem = findViewById(R.id.addItemBtn);
Button deleteItem = findViewById(R.id.deleteItemBtn);
// Set up recyclerview
RecyclerView recyclerView = findViewById(R.id.recyclerView);
ItemViewAdapter itemViewAdapter = new ItemViewAdapter(this, itemName, itemQnt);
recyclerView.setAdapter(itemViewAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
displayData();
// Upon clicking on add item button, start the AddItem screen
addItem.setOnClickListener(v -> {
Intent intent = new Intent(getApplicationContext(), AddItemActivity.class);
startActivity(intent);
});
// Upon clicking on delete item button, start the DeleteItem screen
deleteItem.setOnClickListener(v -> {
Intent intent = new Intent(getApplicationContext(), DeleteItemActivity.class);
startActivity(intent);
});
}
private void displayData() {
Cursor cursor = db.getData();
if (cursor.getCount() == 0) {
Toast.makeText(MainActivity.this, "No data present", Toast.LENGTH_SHORT).show();
return;
}
while (cursor.moveToNext()) {
itemName.add(cursor.getString(0));
itemQnt.add(cursor.getString(1));
}
}
}
ItemViewHolder.java:
public class ItemViewHolder extends RecyclerView.ViewHolder{
TextView nameView;
TextView qntView;
public ItemViewHolder(@NonNull View itemView) {
super(itemView);
nameView = nameView.findViewById(R.id.nameInput);
qntView = qntView.findViewById(R.id.qntInput);
}
}
ItemViewAdapter.java:
public class ItemViewAdapter extends RecyclerView.Adapter<ItemViewHolder> {
Context context;
ArrayList<String> name, quantity;
public ItemViewAdapter(Context context, ArrayList<String> name, ArrayList<String> quantity) {
this.context = context;
this.name = name;
this.quantity = quantity;
}
@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.activity_item_inventory, parent, false);
return new ItemViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
holder.nameView.setText(String.valueOf(name.get(position)));
holder.qntView.setText(String.valueOf(quantity.get(position)));
}
@Override
public int getItemCount() {
return name.size();
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activities.MainActivity">
<!--Inventory List text-->
<TextView
android:id="@+id/inventoryListTxt"
android:layout_width="match_parent"
android:layout_height="65dp"
android:text="@string/inventoryList"
android:textSize="20sp"
android:textStyle="bold"
android:gravity="bottom|center_horizontal"
android:paddingBottom="10dp"
android:background="@color/primary"/>
<!--WIP: Recyclerview that will link with activity_item_inventory
to display individual items and make them adjustable. Currently broken-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="500dp"
android:layout_below="@id/inventoryListTxt"
android:layout_marginTop="10dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"/>
<!--Create button to add item-->
<Button
android:id="@+id/addItemBtn"
android:layout_width="140dp"
android:layout_height="50dp"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:text="@string/addItem"
android:textStyle="bold"
android:paddingStart="20dp"
android:layout_marginStart="10dp"
tools:ignore="RtlSymmetry" />
<!--Create button to delete item-->
<Button
android:id="@+id/deleteItemBtn"
android:layout_width="140dp"
android:layout_height="50dp"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:text="@string/deleteItem"
android:textStyle="bold"
android:layout_marginEnd="10dp"
tools:ignore="RtlSymmetry" />
<!-- Notification Button -->
<ImageButton
android:id="@+id/notificationBtn"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentEnd="true"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:backgroundTint="@color/primary"
android:contentDescription="@string/notificationBtnDesc"
android:scaleType="fitCenter"
android:src="@drawable/baseline_notifications_24"
tools:ignore="ImageContrastCheck" />
</RelativeLayout>
activity_item_inventory.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
app:cardElevation="12dp"
app:cardCornerRadius="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<!-- Display item name column-->
<TextView
android:id="@+id/textItem"
android:text="@string/itemName"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.50"
android:textStyle="bold"
android:paddingEnd="8dp" />
<!-- Display item name input-->
<TextView
android:id="@+id/nameInput"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.50"
android:textStyle="bold"
android:paddingEnd="8dp" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical">
<!-- Display item quantity column-->
<TextView
android:id="@+id/textQuantity"
android:text="@string/itemQnt"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.50"
android:textStyle="bold"
android:paddingEnd="8dp" />
<!-- Display item quantity input-->
<TextView
android:id="@+id/qntInput"
android:textAlignment="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.50"
android:textStyle="bold"
android:paddingEnd="8dp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
ArrayList 在用于函数 displayData 之前已声明但未初始化:
java.lang.NullPointerException:尝试在 com.example.test.activities.MainActivity.displayData 处的空对象引用上调用虚拟方法“boolean java.util.ArrayList.add(java.lang.Object)”
MainActivity.java
onCreate()
ArrayList<String> itemName, itemQnt;
…
显示数据()
itemName.add(cursor.getString(0));