ListView 没有向我显示包含数据库名称的列表。我使用 SimpleCursorAdapter
Posted
技术标签:
【中文标题】ListView 没有向我显示包含数据库名称的列表。我使用 SimpleCursorAdapter【英文标题】:The ListView doesn't show me a list with names from database. I use SimpleCursorAdapter 【发布时间】:2021-09-28 03:18:47 【问题描述】:我正在尝试为我的应用程序实现数据库。这是我第一次这样做。 我有一个带有列表视图的布局,我使用 SimpleCoursorAdapter 将数据从数据库传输到我的 ListView。该应用程序没有显示任何内容。 ListView 是空的,我不知道为什么。
这是我的 TopLevelActivity
public class TopLevelActivity extends Activity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_top_level);
AdapterView.OnItemClickListener itemClickListener =
new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> listView,
View v,
int position,
long id)
if(position == 0)
Intent intent = new Intent(TopLevelActivity.this, DrinkCategoryActivity.class);
startActivity(intent);
if(position == 1)
Intent intent = new Intent(TopLevelActivity.this, SnacksCategoryActivity.class);
startActivity(intent);
;
ListView listView = (ListView) findViewById(R.id.list_options);
listView.setOnItemClickListener(itemClickListener);
来自TopLevelActivity的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:orientation="vertical"
tools:context=".TopLevelActivity">
<ImageView
android:layout_
android:layout_
android:src="@drawable/starbuzz_logo"
android:contentDescription="@string/starbuzz_logo"/>
<ListView
android:id="@+id/list_options"
android:layout_
android:layout_
android:entries="@array/options"/>
</LinearLayout>
我认为这里的 DrinkCategoryActivity 有些错误
public class DrinkCategoryActivity extends Activity
private SQLiteDatabase db;
private Cursor cursor;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_category);
ListView listDrinks = (ListView) findViewById(R.id.list_drinks);
SQLiteOpenHelper coffeinaDatabaseHelper = new CoffeinaDatabaseHelper(this);
try
db = coffeinaDatabaseHelper.getReadableDatabase();
cursor = db.query("DRINK",
new String[]"_id", "NAME",
null, null, null, null, null);
SimpleCursorAdapter listAdapter = new SimpleCursorAdapter
(this,
android.R.layout.simple_list_item_1,
cursor,
new String[]"NAME",
new int[]android.R.id.text1,0
);
listDrinks.setAdapter(listAdapter);
catch (SQLiteException e)
Toast toast = Toast.makeText(this, "Baza danych jest niedostepna",
Toast.LENGTH_SHORT);
toast.show();
AdapterView.OnItemClickListener itemClickListener =
new AdapterView.OnItemClickListener()
public void onItemClick(AdapterView<?> listDrinks,
View itemView,
int position,
long id)
Intent intent = new Intent(DrinkCategoryActivity.this,
DrinkActivity.class);
intent.putExtra(DrinkActivity.EXTRA_DRINKID, (int) id);
startActivity(intent);
;
listDrinks.setOnItemClickListener(itemClickListener);
public void onDestroy()
super.onDestroy();
cursor.close();
db.close();
来自 DrinkCategoryActivity 的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:orientation="vertical"
android:layout_
tools:context=".DrinkCategoryActivity">
<ListView
android:id="@+id/list_drinks"
android:layout_
android:layout_/>
</LinearLayout>
饮酒活动
public class DrinkActivity extends AppCompatActivity
public static final String EXTRA_DRINKID = "drinkId";
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink);
int drinkId = (Integer)getIntent().getExtras().get(EXTRA_DRINKID);
SQLiteOpenHelper starbuzzDatabaseHelper = new CoffeinaDatabaseHelper(this);
try
SQLiteDatabase db = starbuzzDatabaseHelper.getReadableDatabase();
Cursor cursor = db.query("DRINK",
new String[]"NAME", "DESCRIPTION", "IMAGE_RESORUCE_ID",
"_id = ?",
new String[]Integer.toString(drinkId),
null, null, null);
if(cursor.moveToFirst())
String nameText = cursor.getString(0);
String descriptionText = cursor.getString(1);
int photoId = cursor.getInt(2);
TextView name = (TextView)findViewById(R.id.name);
name.setText(nameText);
TextView description = (TextView)findViewById(R.id.description);
description.setText(descriptionText);
ImageView photo = (ImageView)findViewById(R.id.latte);
photo.setImageResource(photoId);
photo.setContentDescription(nameText);
cursor.close();
db.close();
catch (SQLiteException e)
Toast toast = Toast.makeText(this, "Bada danych jest niedostepna",
Toast.LENGTH_SHORT);
toast.show();
来自 DrinkActivity 的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:orientation="vertical"
tools:context=".DrinkActivity">
<ImageView
android:id="@+id/latte"
android:layout_
android:layout_/>
<TextView
android:id="@+id/name"
android:layout_
android:layout_/>
<TextView
android:id="@+id/description"
android:layout_
android:layout_/>
</LinearLayout>
我的 DataBaseHelper 和这里也可能有些错误。 复杂器没有显示任何错误。
package com.hfad.coffeina;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CoffeinaDatabaseHelper extends SQLiteOpenHelper
private static final String DB_NAME = "coffeina";
private static final int DB_VERSION = 2;
CoffeinaDatabaseHelper(Context context)
super(context, DB_NAME, null, DB_VERSION);
public void onCreate(SQLiteDatabase db)
updateMyDatabase(db, 0, DB_VERSION);
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
updateMyDatabase(db, oldVersion, newVersion);
private static void insertDrink(SQLiteDatabase db, String name, String description,
int resourceId)
ContentValues drinkValues = new ContentValues();
drinkValues.put("NAME", name);
drinkValues.put("DESCRIPTION", description);
drinkValues.put("IMAGE_RESOURCE_ID", resourceId);
db.insert("DRINK", null, drinkValues);
private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion)
if(oldVersion < 1)
db.execSQL("CREATE TABLE DRINK (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+"NAME TEXT, "
+"DESCRIPTON TEXT , "
+"IMAGE_RESOURCE_ID INTEGER);");
insertDrink(db, "Latte", "Czarne espresso z gorącym mlekiem i mleczną pianką.",
R.drawable.latte);
insertDrink(db, "Cappucciono", "Czarne espresso z dużą ilościa spienionego mleka",
R.drawable.cappuccino);
insertDrink(db, "Espresso", "Czarna kawa ze świeżo mielonych ziaren najwyższej jakości.",
R.drawable.filter);
if(oldVersion < 2)
db.execSQL("ALTER TABLE DRINK ADD COLUMN FAVORITE NUMERIC;");
来自模拟器enter image description here的打印屏幕
【问题讨论】:
【参考方案1】:问题
我相信您的主要问题是,在 DRINK 表中,您使用 +"DESCRIPTON TEXT , "
定义了列名,但您引用了 DESCRIPTION 列(tion as与吨相反)在其他地方,包括在插入 3 个初始行时。隐藏/伪装,因为它们在 try .... catch 构造中。
请注意,在 try .... catch 中包装 SQLite 内容通常没有帮助并导致混淆,尤其是在测试时未检查日志的情况下。
那是日志会显示类似:-
07-21 17:29:20.748 4340-4340/a.a.so68457788javesqlitelistview E/SQLiteLog: (1) table DRINK has no column named DESCRIPTION
07-21 17:29:20.749 4340-4340/a.a.so68457788javesqlitelistview E/SQLiteDatabase: Error inserting NAME=Latte DESCRIPTION=Czarne espresso z gorącym mlekiem i mleczną pianką. IMAGE_RESOURCE_ID=10
android.database.sqlite.SQLiteException: table DRINK has no column named DESCRIPTION (code 1): , while compiling: INSERT INTO DRINK(NAME,DESCRIPTION,IMAGE_RESOURCE_ID) VALUES (?,?,?)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:887)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:498)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1469)
at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1341)
at a.a.so68457788javesqlitelistview.CoffeinaDatabaseHelper.insertDrink(CoffeinaDatabaseHelper.java:32)
at a.a.so68457788javesqlitelistview.CoffeinaDatabaseHelper.updateMyDatabase(CoffeinaDatabaseHelper.java:42)
at a.a.so68457788javesqlitelistview.CoffeinaDatabaseHelper.onCreate(CoffeinaDatabaseHelper.java:18)
因此数据库将是空的,因此 ListView 什么也不显示。
我建议始终对数据库组件使用单一定义,并始终使用单一定义引用组件。
建议的修复/改进
也许考虑使用:-
class CoffeinaDatabaseHelper extends SQLiteOpenHelper
private static final String DB_NAME = "coffeina";
private static final int DB_VERSION = 2;
public static final String DRINK_TABLENAME = "DRINK";
public static final String DRINK_ID_COLUMN = BaseColumns._ID; // Android _id column name
public static final String DRINK_NAME_COLUMN = "NAME";
public static final String DRINK_DESCRIPTION_COLUMN = "DESCRIPTION";
public static final String DRINK_IMAGE_RESOURCE_ID_COLUMN = "IMAGE_RESOURCE_ID";
public static final String DRINK_FAVORITE_COLUMN = "FAVOURITE";
CoffeinaDatabaseHelper(Context context)
super(context, DB_NAME, null, DB_VERSION);
public void onCreate(SQLiteDatabase db)
updateMyDatabase(db, 0, DB_VERSION);
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
updateMyDatabase(db, oldVersion, newVersion);
private static void insertDrink(SQLiteDatabase db, String name, String description,
int resourceId)
ContentValues drinkValues = new ContentValues();
drinkValues.put(DRINK_NAME_COLUMN, name);
drinkValues.put(DRINK_DESCRIPTION_COLUMN, description);
drinkValues.put(DRINK_IMAGE_RESOURCE_ID_COLUMN, resourceId);
db.insert(DRINK_TABLENAME, null, drinkValues);
private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion)
if(oldVersion < 1)
/* no need for autoincrement id's will be generated without the overheads
check https://sqlite.org/autoinc.html for details/why
*/
db.execSQL("CREATE TABLE " + DRINK_TABLENAME + " (" + DRINK_ID_COLUMN + " INTEGER PRIMARY KEY, "
+ DRINK_NAME_COLUMN + " TEXT,"
+ DRINK_DESCRIPTION_COLUMN +" TEXT , "
+ DRINK_IMAGE_RESOURCE_ID_COLUMN + " INTEGER);");
insertDrink(db, "Latte", "Czarne espresso z gorącym mlekiem i mleczną pianką.",10);
insertDrink(db, "Cappucciono", "Czarne espresso z dużą ilościa spienionego mleka", 11);
insertDrink(db, "Espresso", "Czarna kawa ze świeżo mielonych ziaren najwyższej jakości.", 12);
if(oldVersion < 2)
db.execSQL("ALTER TABLE DRINK ADD COLUMN " + DRINK_FAVORITE_COLUMN + " NUMERIC;");
注意用于测试图像资源 id 的已编好,需要更改以反映您的原始代码。
然后随后使用常量在别处引用数据库组件。例如,考虑以下版本的 DrinkCategoryActivity 类:-
public class DrinkCategoryActivity extends AppCompatActivity
CoffeinaDatabaseHelper coffeinaDatabaseHelper; //<<<<< ADDED you want instance of YOUR helper not an SQLiteOpenHelper
SQLiteDatabase db;
Cursor cursor;
SimpleCursorAdapter listAdapter; //<<<<< Better here, more scope
ListView listDrinks;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink_category);
listDrinks = (ListView) findViewById(R.id.list_drinks);
// SQLiteOpenHelper coffeinaDatabaseHelper = new CoffeinaDatabaseHelper(this);
coffeinaDatabaseHelper = new CoffeinaDatabaseHelper(this);
db = coffeinaDatabaseHelper.getWritableDatabase(); // get readable will typically get writeable anyway
setOrRefreshListView();
private void setOrRefreshListView()
cursor = db.query(CoffeinaDatabaseHelper.DRINK_TABLENAME,
new String[]"_id", CoffeinaDatabaseHelper.DRINK_NAME_COLUMN,
null, null, null, null, null);
if (listAdapter == null)
listAdapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1, cursor,
new String[]"NAME",
new int[]android.R.id.text1, 0);
listDrinks.setAdapter(listAdapter);
listDrinks.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l)
Intent intent = new Intent(view.getContext(), DrinkActivity.class);
intent.putExtra(DrinkActivity.EXTRA_DRINKID, l);
startActivity(intent);
);
else
listAdapter.swapCursor(cursor);
/* If returning to Activity (from DrinkActivity) refresh the ListView
just in case it has changed
*/
@Override
protected void onResume()
super.onResume();
setOrRefreshListView();
@Override
protected void onDestroy()
super.onDestroy();
cursor.close();
然后使用上面的:-
附加
进一步了解上述内容,DrinkActity 的工作(尽管没有图像)和更简洁的版本是:-
public class DrinkActivity extends AppCompatActivity
public static final String EXTRA_DRINKID = "drinkId";
CoffeinaDatabaseHelper DBHelper;
SQLiteDatabase db;
TextView name,description;
ImageView photo;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drink);
long drinkId = this.getIntent().getLongExtra(DrinkActivity.EXTRA_DRINKID,-1); // Should be LONG
DBHelper = new CoffeinaDatabaseHelper(this);
db = DBHelper.getWritableDatabase();
name = this.findViewById(R.id.name);
description = this.findViewById(R.id.description);
Cursor cursor = db.query(CoffeinaDatabaseHelper.DRINK_TABLENAME,
null,
CoffeinaDatabaseHelper.DRINK_ID_COLUMN +" = ?",
new String[]String.valueOf(drinkId), // cope with Long
null, null, null);
if(cursor.moveToFirst())
name.setText(cursor.getString(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_NAME_COLUMN)));
description.setText(cursor.getString(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_DESCRIPTION_COLUMN)));
//<<<<< COMMENTED OUT FOR TESTING (as invalid resource id's have been used) >>>>>
//photo.setImageResource(cursor.getInt(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_IMAGE_RESOURCE_ID_COLUMN)));
//photo.setContentDescription(cursor.getString(cursor.getColumnIndex(CoffeinaDatabaseHelper.DRINK_NAME_COLUMN)));
else
Toast.makeText(this, "Bada danych jest niedostepna", Toast.LENGTH_SHORT).show();
cursor.close();
//db.close(); don't close, resource expensive to open
所以选择拿铁咖啡会给出:-
【讨论】:
我检查你的修复版本。首先,我看看你做了什么,我正在实现它,它仍然无法正常工作,而不是我复制你的代码并粘贴到我的 android studio 并且仍然是相同的 Table 是空的并且 ListView 显示 nothink 但是当我检查平板电脑模拟器时比工作在电话上没有,但为什么 @JacobNatural 您可能需要在手机上重新安装。一旦数据库被创建,如果停留在那里,那么 onCreate 就不会再次运行。重新安装会删除数据库。 我无法打开光标。我的 DrinkActivity 不起作用。我复制了您的代码,但仍然没有。我再次从手机安装中删除了应用程序,但仍然没有。 好的,我解决了这个问题。当我创建表时,我有 PRIMARY KEY 而不是 INTEGER PRIMARY KEY以上是关于ListView 没有向我显示包含数据库名称的列表。我使用 SimpleCursorAdapter的主要内容,如果未能解决你的问题,请参考以下文章
从数据库中获取列表并在 Listview 中显示需要很长时间