使用Button更新SQLite DB,单击listView

时间:2018-01-19 22:23:46

标签: android sqlite listview android-cursoradapter

我正在尝试构建一个简单的股票应用程序,我在我的主要活动上有一个列表视图,在我拥有的每个列表项目上都有一个“卖出”按钮。 “卖出”按钮的功能应通过更新该项目的行并将数量设置为数量-1来减少该特定项目的数量。

为了实现这一点,我发现在我的自定义游标适配器类中设置一个on click侦听器就是这样做的。我正在使用内容提供程序类进行数据库操作。所以我试图做的是,在我的主要活动中触发一个函数,在我的游标适配器中的O​​nClickListener中。这里有一些代码可以解释更多。 (请原谅我糟糕的编程技巧,我相当新)

我的方法似乎由于某种原因不起作用,首先点击“销售”按钮不会执行任何操作,第二个方法会崩溃应用程序,原因如下:

  android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method.

P.S。我没有从适配器发送上下文来减少count方法,并且它在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;
}

我在主要活动中编写(或试图写)的函数

    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)));
        }
    });

提前谢谢!

1 个答案:

答案 0 :(得分:1)

问题非常重要。我修改了你的代码。首先不要从活动中创建对象。尝试使用装箱和拆箱技术来检索您的上下文。在你的com.someguyfortune.MyAwesomeApp构造函数中应该是这样的

InsertCursorAdapter

然后,您需要保存public ItemCursorAdapter(Context context, Cursor c) { super(context, c); this.context = context; }方法中的cursor

然后,您需要绑定上下文对象以获取活动对象。总而言之,你会有这样的事情:

bindView

我也更改了你的 @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方法是超类getContentResolver()中的一种方法,因为它是公开的,所以您的活动已经实现了它。

AppCompatActivity