【问题标题】:Updating ListView with CursorAdapter after an OnClick changes a value in SQLite database?OnClick 更改 SQLite 数据库中的值后使用 CursorAdapter 更新 ListView?
【发布时间】:2017-05-17 20:28:58
【问题描述】:

第一次在这个网站上提问,但是我已经用这个网站了
通过制作我的项目来解决我的大部分其他问题 优达学城。

我有一个库存应用程序,可以在 SQLite 数据库中存储和显示项目,除了与每个项目配对的销售按钮外,所有功能都是完整的。 Here is a screenshot, including the sale button

Sale 按钮当前会将数据库中的数量减少 1,但它不会更新屏幕截图中的 Listview 数量,它更新的唯一方法是单击该项目进入详细项目屏幕并然后点击返回按钮。

我相信答案在于我研究的 changeCursor()notifyDataSetChanged(),但我无法将其应用于我的代码以产生任何效果。

ItemCursorAdapter

public ItemCursorAdapter(Context context, Cursor c) {
    super(context, c, 0);
}


@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {

    return LayoutInflater.from(context).inflate(R.layout.list_layout, parent, false);
}

@Override

public void bindView(final View view, final Context context, final Cursor mCursor) {
    TextView itemName = (TextView) view.findViewById(R.id.list_item_name);
    TextView itemQty = (TextView) view.findViewById(R.id.list_ItemQty);
    TextView locText = (TextView) view.findViewById(R.id.list_ItemLocation);
    TextView priceText = (TextView) view.findViewById(R.id.list_ItemPrice);
    final Button saleButton = (Button) view.findViewById(R.id.list_salebutton);
    //get values from cursor

    int nameColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_NAME);
    int qtyColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_QUANTITY_HAVE);
    int locColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_LOCATION);
    int priceColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_QUANTITY_WANT);
    int idColumnIndex = mCursor.getColumnIndex(DBhelper.KEY_ID);
    //Populate fields with values
    String itemNameString = mCursor.getString(nameColumnIndex);
    QUANTITY_HAVESTRING = mCursor.getString(qtyColumnIndex);
    String locationString = mCursor.getString(locColumnIndex);
    String priceString = mCursor.getString(priceColumnIndex);
    SELECTEDITEM_SOLD_BUTTON = mCursor.getString(idColumnIndex);

    //Adds tags to the Sale Buttons as they are created, Quantity and ID
    saleButton.setTag(R.id.tagQuantity, mCursor.getString(qtyColumnIndex));
    saleButton.setTag(R.id.tagID, mCursor.getString(idColumnIndex));


    itemName.setText(itemNameString);
    itemQty.setText(QUANTITY_HAVESTRING);
    locText.setText(locationString);
    priceText.setText("$" + priceString);

    saleButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String tagID = (String) saleButton.getTag(R.id.tagID);
            String tagQuantity = (String) saleButton.getTag(R.id.tagQuantity);



            if (Integer.parseInt(tagQuantity) > 0) {
                DBhelper mDBhelper = new DBhelper(mContext);
                SQLiteDatabase db = mDBhelper.getWritableDatabase();

                ContentValues values = new ContentValues();
                values.put(DBhelper.KEY_QUANTITY_HAVE, (Integer.parseInt(tagQuantity) - 1));
                db.update(DBhelper.TABLE_INVENTORY, values, "_id = " + tagID, null);

                Toast.makeText(mContext, itemAdapter.toString(), Toast.LENGTH_SHORT).show();

                itemAdapter.changeCursor(mCursor);
                itemAdapter.notifyDataSetChanged();



            }
        }
    });


    //todo add on destroy db close

     }

}

MainActivity

    public class MainActivity extends AppCompatActivity {

    private DBhelper mDBhelper;
    public Cursor cursor;
    public static ItemCursorAdapter itemAdapter;
    public static ListView lvItems;

    // ON CREATE
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDBhelper = new DBhelper(this);


    }


    // ON CREATE OPTIONS MENU
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu options from the res/menu/menu_catalog.xml file.
        // This adds menu items to the app bar.
        getMenuInflater().inflate(R.menu.inventory_menu_main, menu);
        return true;
    }

    //ACTION BAR MENU when clicked
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        SQLiteDatabase db = mDBhelper.getWritableDatabase();
        // User clicked on a menu option in the app bar overflow menu
        switch (item.getItemId()) {


            // Respond to a click on the "Delete all entries" menu option
            case R.id.action_delete_all_entries:


                db.delete(DBhelper.TABLE_INVENTORY, null, null);
                onStart();
                return true;
//Populate Standard Items, that the app is primarily designed to track.
            case R.id.action_add_standard_entries_entries:

                String[] INSERT_ROWS = getResources().getStringArray(R.array.artilleryEquipmentRows);


                for (int i = 0; i < 33; i++)
                    db.execSQL(INSERT_ROWS[i]);
                onStart();
                return true;


//ABOUT APP INFO
            case R.id.action_display_appInfo:

                AlertDialog aboutDialog = new AlertDialog.Builder(MainActivity.this).create();
                aboutDialog.setTitle(MainActivity.this.getString(R.string.aboutDialogTitle));
                aboutDialog.setMessage(MainActivity.this.getString(R.string.aboutDialogMessage));
                //TODO set a icon
                aboutDialog.setButton(AlertDialog.BUTTON_NEUTRAL, MainActivity.this.getString(R.string.confirmDialogOk),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();

                            }


                        });
                aboutDialog.show();
                return true;


            // Add new Item Button (Shows up as a + sign)
            case R.id.action_additem:
                Intent intent = new Intent(MainActivity.this, AddItemActivity.class);
                startActivity(intent);

                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStart() {
        super.onStart();
        displayDatabaseInfo();
    }


    // Populates the list
    public void displayDatabaseInfo() {
        // Create and/or open a database to read from it
        SQLiteDatabase db = mDBhelper.getReadableDatabase();

        // Define a projection that specifies which columns from the database
        // you will actually use after this query.

        String[] projection = {
                DBhelper.KEY_ID,
                DBhelper.KEY_NAME,
                DBhelper.KEY_QUANTITY_HAVE,
                DBhelper.KEY_QUANTITY_WANT,
                DBhelper.KEY_LOCATION,
                DBhelper.KEY_ISSUED_BOOLEAN};

        // Perform a query on the pets table
        cursor = db.query(
                DBhelper.TABLE_INVENTORY,   // The table to query
                projection,            // The columns to return
                null,                  // The columns for the WHERE clause
                null,                  // The values for the WHERE clause
                null,                  // Don't group the rows
                null,                  // Don't filter by row groups
                null);                   // The sort order

        ListView lvItems = (ListView) findViewById(R.id.main_list_view);
        itemAdapter = new ItemCursorAdapter(this, cursor);
        lvItems.setAdapter(itemAdapter);


//Assigns Empty View for when no items in Database
        View emptyView = findViewById(R.id.empty_view);
        lvItems.setEmptyView(emptyView);

        lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long passID) {


                Intent intent = new Intent(MainActivity.this, AddItemActivity.class);
                intent.putExtra("itemPosition", passID);
                startActivity(intent);
            }
        });

    }


    //Closes the cursor on app termination
    @Override
    protected void onDestroy() {
        super.onDestroy();
        cursor.close();
        Log.d("tag", "Cursor(MainActivity) Closed");
    }
}

【问题讨论】:

  • itemAdapter 里面是什么ItemCursorAdapter
  • 我尝试将 MainActivity 中的 itemAdapter 设为全局静态变量,以便可以从 CursorAdapter 访问它,这可能是我的问题吗?我发现另一个帖子似乎表明这样做是一种解决方案。
  • 您不应该使用static 在类之间共享值。相反,static 变量旨在为单个类的所有实例提供相同的单个值。在这种情况下,每个MainActivity 实例都应该有自己的CursorAdapter 实例,所以静态是不合适的。

标签: java android sqlite android-cursoradapter


【解决方案1】:

您可以通过缓慢的方式执行此操作,但仍在寻找更好的解决方案,但我找不到

使用restartLoader getLoaderManager().restartLoader(0, null, Activity.this); mAdapter.notifyDataSetChanged();

【讨论】:

    【解决方案2】:

    尝试改变

     itemAdapter.changeCursor(mCursor);
     itemAdapter.notifyDataSetChanged();
    

     changeCursor(mCursor);
     notifyDataSetChanged();
    

    它应该可以工作。

    【讨论】:

      【解决方案3】:

      我解决了一些问题,足以为该项目上交。

          saleButton.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
      
              TextView itemQty = (TextView) view.findViewById(R.id.list_ItemQty);
              String itemQtyString = itemQty.getText().toString();
              int itemQtyInt = Integer.parseInt(itemQtyString);
      
              String tagID = (String) saleButton.getTag(R.id.tagID);
              String tagQuantity = (String) saleButton.getTag(R.id.tagQuantity);
      
      
              if (itemQtyInt > 0) {
      
                  itemQtyInt = itemQtyInt - 1;
      
                  itemQtyString = Integer.toString(itemQtyInt);
                  DBhelper mDBhelper = new DBhelper(mContext);
                  SQLiteDatabase db = mDBhelper.getWritableDatabase();
      
                  ContentValues values = new ContentValues();
                  values.put(DBhelper.KEY_QUANTITY_HAVE, itemQtyInt);
                  db.update(DBhelper.TABLE_INVENTORY, values, "_id = " + tagID, null);
      
                  itemQty.setText(itemQtyString);
      

      【讨论】:

        【解决方案4】:

        由于onClick()的代码在ItemCursorAdapter里面,你只需要调用

        notifyDataSetChanged();
        

        您无需调用changeCursor(),因为当前光标可以重复使用。

        【讨论】:

        • 谢谢,我确实解决了这个问题,尽管这可能不是最有效的方式。有趣的是,如果我输入 notifyDataSetChanged();它会阻止它正常工作。
        • @NicholasCherryholmes 您应该选择 notifyDataSetChanged()changeCursor(),但不能同时使用。
        【解决方案5】:

        我也一直在做这门课程,遇到了同样的问题,虽然我认为我走的是不同的路线,也许它更优雅一点?诀窍是使用 TextView 文本来获取数量值。

        这是来自我的自定义 CursorAdapter:

        // Quantity Button
            ImageButton button = (ImageButton) view.findViewById(R.id.sales_button);
            // Get the current items ID
            int currentId = cursor.getInt(cursor.getColumnIndex(InventoryEntry._ID));
            // Make the content uri for the current Id
            final Uri contentUri = Uri.withAppendedPath(InventoryEntry.CONTENT_URI, Integer.toString(currentId));
        
            // Change the quantity when you click the button
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    TextView quantityView = (TextView) view.findViewById(R.id.quantity);
                    int quantity = Integer.valueOf(quantityView.getText().toString());
        
                    if (quantity > 0) {
                        quantity = quantity - 1;
                    }
                    // Content Values to update quantity
                    ContentValues values = new ContentValues();
                    values.put(InventoryEntry.COLUMN_QUANTITY, quantity);
        
                    // update the database
                    context.getContentResolver().update(contentUri, values, null, null);
                }
            });
        

        您不通知适配器中的更改,按照您的预期在 Provider 中执行,并使用 mAdapter.swapCursor() 函数更改 MainActivity 的 LoaderManager 回调中的光标。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-09
          • 2017-06-29
          • 2011-04-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多