当我单击应该让我进入此列表视图活动的项目时,应用程序崩溃了,我不知道我做错了什么,也不知道我需要做什么来纠正它。这是我的 CursorAdapter 子类,用于显示列表视图:
package com.example.marhbabikapp;
import android.content.Context;import android.database.Cursor;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.CursorAdapter;import android.widget.ImageView;import android.widget.TextView;
import com.bumptech.glide.Glide;
public class DestinationCursorAdapter extends CursorAdapter {MyDBHandler myDBHandler;
public DestinationCursorAdapter(Context context, Cursor cursor,int flags ,MyDBHandler dbHandler) {
super(context, cursor, flags);
this.myDBHandler = dbHandler;;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.item_destinationtype, parent, false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView nameTextView = view.findViewById(R.id.destinationTextViewName);
TextView descriptionTextView = view.findViewById(R.id.destinationTextViewDescription);
ImageView imageView = view.findViewById(R.id.destinationImageView);
String name = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.DESTINATION_NAME));
String description = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.DESTINATION_DESCRIPTION));
String imageUrl = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.PHOTO_URL));
nameTextView.setText(name);
descriptionTextView.setText(description);
Glide.with(context)
.load(imageUrl)
//.placeholder(R.drawable.placeholder_image) // Placeholder image while loading
//.error(R.drawable.error_image) // Error image if Glide fails to load
.into(imageView);
}
}
这是我尝试放置列表视图时的 types_screen 活动:
包 com.example.marhbabikapp;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;import android.content.Intent;import android.database.Cursor;import android.os.Bundle;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;
import java.util.Locale;
public class Types_screen extends AppCompatActivity {
private ListView mylistView;
private MyDBHandler dbHandler;
private DestinationCursorAdapter destinationCursorAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_types_screen);
Intent intent = getIntent();
String type = intent.getStringExtra("DESTINATION_TYPE");
mylistView = findViewById(R.id.listViewDestinations);
dbHandler = new MyDBHandler(this);
Cursor cursor = null;
if ("Historical".equals(type.trim())) {
cursor = dbHandler.getHistoricalDestinationsCursor();
} else if ("Natural".equals(type.trim())) {
cursor = dbHandler.getNaturalDestinationsCursor();
} else if ("Coastal".equals(type.trim())) {
cursor = dbHandler.getCoastalDestinationsCursor();
} else if ("Modern".equals(type.trim())) {
cursor = dbHandler.getModernDestinationsCursor();
} else if ("Cultural".equals(type.trim())) {
cursor = dbHandler.getCulturalDestinationsCursor();
} else if ("Saharian".equals(type.trim())) {
cursor = dbHandler.getSaharianDestinationsCursor();
} else if ("Snowy".equals(type.trim())) {
cursor = dbHandler.getSnowyDestinationsCursor();
}
destinationCursorAdapter = new DestinationCursorAdapter(this, cursor, 0, dbHandler);
mylistView.setAdapter(destinationCursorAdapter);
}
}
这是这些方法的一个实例: 公共光标 getSnowyDestinationsCursor() { SQLiteDatabase db = this.getReadableDatabase();
String[] projection = {
DESTINATION_NAME,
DESTINATION_DESCRIPTION,
PHOTO_URL,
REGION
};
String selection = SNOWY + " = ?";
String[] selectionArgs = { "1" };
return db.query(
TABLE_DESTINATIONS,
projection,
selection,
selectionArgs,
null,
null,
null
);
}
毫无疑问,但不能消除其他问题,您错过了 CursorAdapter 的 CRUCIAL 方面。
> 光标必须包含名为“_id”的列,否则此类将无法工作。
没有明确解释的是,该列应该是唯一标识单行的整数(长)值。通常隐藏的 rowid (对于普通表)符合这些要求。
the_column_name_often_id_or_underscore_id INTEGER PRIMARY KEY
(有或没有 AUTOINCREMENT
(如果实际上不需要,那就浪费了))
INTEGER
(与大小写无关)不任何其他内容,例如INT
。假设有一个普通表(例如,不是没有 ROWID 或虚拟表),可以使用以下快速修复:-
String[] projection = {
"rowid AS " + BaseColumns._ID, /*<<<<<<<<<< ADDED */
DESTINATION_NAME,
DESTINATION_DESCRIPTION,
PHOTO_URL,
REGION
};
这将克服引发的非法参数异常(假设代码到目前为止)。
问题演示
演示如何使用您的代码(做出许多假设),然后:-
2024-01-31 12:18:35.343 2228-2228/a.a.so77904630cursdoradapter D/AndroidRuntime: Shutting down VM
--------- beginning of crash
2024-01-31 12:18:35.344 2228-2228/a.a.so77904630cursdoradapter E/AndroidRuntime: FATAL EXCEPTION: main
Process: a.a.so77904630cursdoradapter, PID: 2228
java.lang.RuntimeException: Unable to start activity ComponentInfo{a.a.so77904630cursdoradapter/a.a.so77904630cursdoradapter.MainActivity}: java.lang.IllegalArgumentException: column '_id' does not exist. Available columns: [destination_name, destination_description, photo_url, region]
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.IllegalArgumentException: column '_id' does not exist. Available columns: [destination_name, destination_description, photo_url, region]
at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:340)
at android.widget.CursorAdapter.init(CursorAdapter.java:180)
at android.widget.CursorAdapter.<init>(CursorAdapter.java:157)
at a.a.so77904630cursdoradapter.DestinationCursorAdapter.<init>(DestinationCursorAdapter.java:14)
at a.a.so77904630cursdoradapter.MainActivity.setOrRefreshListView(MainActivity.java:56)
at a.a.so77904630cursdoradapter.MainActivity.onCreate(MainActivity.java:28)
即Destination CursorAdapter的第14行是发生异常的地方,也就是
super(context, cursor, flags);
这条信息非常清楚。
已修复
只需更改为使用:-
String[] projection = {
"rowid AS " + BaseColumns._ID, /* ADDED */
DESTINATION_NAME,
DESTINATION_DESCRIPTION,
PHOTO_URL,
REGION
};
然后:-
onCreate
方法的一部分插入的)。