使用按钮单击 listView 更新 SQLite 数据库
Updating the SQLite DB with a Button click on listView
我正在尝试构建一个简单的股票应用程序,我的主 activity 上有一个列表视图,它在我拥有的每个列表项上都有一个 "Sell" 按钮。 “销售”按钮的功能应该通过更新该项目的行并将数量设置为 quantity-1 来减少该特定项目的数量。
为了实现这一点,我发现在我的自定义光标适配器 class 中设置一个点击侦听器是实现它的方法。我正在为我的数据库操作使用内容提供程序 class。所以我试图做的是,在我的游标适配器中的 OnClickListener 中触发一个位于我的主要 activity 中的函数。这是一些可以解释更多的代码。 (请原谅我糟糕的编程技能,我是新手)
由于某种原因,我的方法似乎不起作用,第一次点击“出售”按钮没有做任何事情,第二次导致应用程序崩溃,原因是:
android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method.
p.s。我没有从适配器发送上下文来减少计数方法,它在 getContentResolver() 上崩溃了一个空指针。
我的内容提供商中的更新功能:
private int updateItem (Uri uri, ContentValues values, String selection, String[] selectionArgs){
if (values.containsKey(InventoryContract.ItemEntry.COLUMN_NAME)){
String name = values.getAsString(InventoryContract.ItemEntry.COLUMN_NAME);
if (name == null){
throw new IllegalArgumentException("Item requires a name");
}
}
// If values size is zero, do not try to update the database.
if (values.size() == 0){
return 0;
}
// Otherwise, get writeable database to update the data
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Perform the update on the database and get the number of rows affected
int rowsUpdated = database.update(InventoryContract.ItemEntry.TABLE_NAME, values, selection, selectionArgs);
// If 1 or more rows were updated, then notify all listeners that the data at the
// given URI has changed
if (rowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
// Return number of rows updated
return rowsUpdated;
}
我在主程序中编写(或尝试编写)的功能activity
public void decreaseCount(Context context, int columnId, int quantity){
quantity = quantity -1;
ContentValues values = new ContentValues();
values.put(InventoryContract.ItemEntry.COLUMN_QUANTITY, quantity);
Uri updateUri = ContentUris.withAppendedId(InventoryContract.ItemEntry.CONTENT_URI, columnId);
int rowsAffected = context.getContentResolver().update(updateUri, values,null, null);
}
最后,我添加到按钮的自定义 OnClickListener(p.s。侦听器位于光标适配器的覆盖 bindView 方法中)
sellButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int columnIdIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry._ID);
int quantityIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry.COLUMN_QUANTITY);
CatalogActivity catalogActivity = new CatalogActivity();
catalogActivity.decreaseCount(context2, Integer.valueOf(mCursor.getString(columnIdIndex)), Integer.valueOf(mCursor.getString(quantityIndex)));
}
});
提前致谢!
问题很简单。我修复了你的代码。首先不要从活动中创建对象。尝试使用装箱和拆箱技术来检索您的上下文。在你的 InsertCursorAdapter
构造函数中应该是这样的
public ItemCursorAdapter(Context context, Cursor c) {
super(context, c);
this.context = context;
}
然后您需要从 bindView
方法中保存您的 cursor
。
然后您需要绑定上下文对象以取回您的 activity 对象。总而言之,你会得到这样的东西:
@Override
public void bindView(View view, final Context context, Cursor cursor) {
this.mCursor = cursor;
TextView nameTextView = view.findViewById(R.id.name);
TextView quantityTextView = view.findViewById(R.id.quantity);
sellButton = view.findViewById(R.id.sell_button);
ImageView imageView = view.findViewById(R.id.item_image);
sellButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int columnIdIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry._ID);
int quantityIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry.COLUMN_QUANTITY);
String col= mCursor.getString(columnIdIndex);
String quan= mCursor.getString(quantityIndex);
CatalogActivity catalogActivity = (CatalogActivity) context;
catalogActivity.decreaseCount( Integer.valueOf(col), Integer.valueOf(quan));
}
});
我还更改了您的 decreaseCount
参数。因为此方法在 activity
class 中,所以您无需在需要减小值的任何时候传递它。 getContentResolver()
方法是 super class AppCompatActivity
中的一个方法,因为它是 public,你的 activity 已经实现了它。
//TODO: Decrease count by one
public void decreaseCount(int columnId, int quantity){
quantity = quantity -1;
ContentValues values = new ContentValues();
values.put(InventoryContract.ItemEntry.COLUMN_QUANTITY, quantity);
Uri updateUri = ContentUris.withAppendedId(InventoryContract.ItemEntry.CONTENT_URI, columnId);
int rowsAffected = getContentResolver().update(updateUri, values,null, null);
}
我正在尝试构建一个简单的股票应用程序,我的主 activity 上有一个列表视图,它在我拥有的每个列表项上都有一个 "Sell" 按钮。 “销售”按钮的功能应该通过更新该项目的行并将数量设置为 quantity-1 来减少该特定项目的数量。
为了实现这一点,我发现在我的自定义光标适配器 class 中设置一个点击侦听器是实现它的方法。我正在为我的数据库操作使用内容提供程序 class。所以我试图做的是,在我的游标适配器中的 OnClickListener 中触发一个位于我的主要 activity 中的函数。这是一些可以解释更多的代码。 (请原谅我糟糕的编程技能,我是新手)
由于某种原因,我的方法似乎不起作用,第一次点击“出售”按钮没有做任何事情,第二次导致应用程序崩溃,原因是:
android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method.
p.s。我没有从适配器发送上下文来减少计数方法,它在 getContentResolver() 上崩溃了一个空指针。
我的内容提供商中的更新功能:
private int updateItem (Uri uri, ContentValues values, String selection, String[] selectionArgs){
if (values.containsKey(InventoryContract.ItemEntry.COLUMN_NAME)){
String name = values.getAsString(InventoryContract.ItemEntry.COLUMN_NAME);
if (name == null){
throw new IllegalArgumentException("Item requires a name");
}
}
// If values size is zero, do not try to update the database.
if (values.size() == 0){
return 0;
}
// Otherwise, get writeable database to update the data
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Perform the update on the database and get the number of rows affected
int rowsUpdated = database.update(InventoryContract.ItemEntry.TABLE_NAME, values, selection, selectionArgs);
// If 1 or more rows were updated, then notify all listeners that the data at the
// given URI has changed
if (rowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
// Return number of rows updated
return rowsUpdated;
}
我在主程序中编写(或尝试编写)的功能activity
public void decreaseCount(Context context, int columnId, int quantity){
quantity = quantity -1;
ContentValues values = new ContentValues();
values.put(InventoryContract.ItemEntry.COLUMN_QUANTITY, quantity);
Uri updateUri = ContentUris.withAppendedId(InventoryContract.ItemEntry.CONTENT_URI, columnId);
int rowsAffected = context.getContentResolver().update(updateUri, values,null, null);
}
最后,我添加到按钮的自定义 OnClickListener(p.s。侦听器位于光标适配器的覆盖 bindView 方法中)
sellButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int columnIdIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry._ID);
int quantityIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry.COLUMN_QUANTITY);
CatalogActivity catalogActivity = new CatalogActivity();
catalogActivity.decreaseCount(context2, Integer.valueOf(mCursor.getString(columnIdIndex)), Integer.valueOf(mCursor.getString(quantityIndex)));
}
});
提前致谢!
问题很简单。我修复了你的代码。首先不要从活动中创建对象。尝试使用装箱和拆箱技术来检索您的上下文。在你的 InsertCursorAdapter
构造函数中应该是这样的
public ItemCursorAdapter(Context context, Cursor c) {
super(context, c);
this.context = context;
}
然后您需要从 bindView
方法中保存您的 cursor
。
然后您需要绑定上下文对象以取回您的 activity 对象。总而言之,你会得到这样的东西:
@Override
public void bindView(View view, final Context context, Cursor cursor) {
this.mCursor = cursor;
TextView nameTextView = view.findViewById(R.id.name);
TextView quantityTextView = view.findViewById(R.id.quantity);
sellButton = view.findViewById(R.id.sell_button);
ImageView imageView = view.findViewById(R.id.item_image);
sellButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int columnIdIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry._ID);
int quantityIndex = mCursor.getColumnIndex(InventoryContract.ItemEntry.COLUMN_QUANTITY);
String col= mCursor.getString(columnIdIndex);
String quan= mCursor.getString(quantityIndex);
CatalogActivity catalogActivity = (CatalogActivity) context;
catalogActivity.decreaseCount( Integer.valueOf(col), Integer.valueOf(quan));
}
});
我还更改了您的 decreaseCount
参数。因为此方法在 activity
class 中,所以您无需在需要减小值的任何时候传递它。 getContentResolver()
方法是 super class AppCompatActivity
中的一个方法,因为它是 public,你的 activity 已经实现了它。
//TODO: Decrease count by one
public void decreaseCount(int columnId, int quantity){
quantity = quantity -1;
ContentValues values = new ContentValues();
values.put(InventoryContract.ItemEntry.COLUMN_QUANTITY, quantity);
Uri updateUri = ContentUris.withAppendedId(InventoryContract.ItemEntry.CONTENT_URI, columnId);
int rowsAffected = getContentResolver().update(updateUri, values,null, null);
}