如何使用 Recycler View 的长按位置获取 SQLite 列值?
Posted
技术标签:
【中文标题】如何使用 Recycler View 的长按位置获取 SQLite 列值?【英文标题】:How do I get an SQLite column value using the on long click position of a Recycler View? 【发布时间】:2021-12-01 21:59:03 【问题描述】:我正在尝试通过长按该行从我的 SQLite 表中删除项目(最终将使用一个按钮,但现在只是长按测试)。但是我正在努力删除正确的。对于上下文,当我向表中添加新行时,它们会得到一个 ID 号。然后我想在长按时使用该 ID 号删除它们。我已经删除了一些下面不相关的代码。
MainActivity.java:
public class MainActivity extends AppCompatActivity implements StockViewInterface
private DBHandler db;
private Stock stock;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView stockView = findViewById(R.id.rvStock);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
stockView.setLayoutManager(linearLayoutManager);
stockView.setHasFixedSize(true);
db = new DBHandler(this);
stock = new Stock();
ArrayList<Stock> allStock = db.getAllStock();
if (allStock.size() > 0)
stockView.setVisibility(View.VISIBLE);
StockAdapter stockAdapter = new StockAdapter(this, allStock, this);
stockView.setAdapter(stockAdapter);
else
stockView.setVisibility(View.GONE);
Toast.makeText(this, "No Items!", Toast.LENGTH_LONG).show();
@Override
public void onLongItemClick(int position)
Toast.makeText(this, "long pressed", Toast.LENGTH_SHORT).show();
db.deleteStockItem(db.getStockItem(stock.getID()));
DBHandler.java:
public class DBHandler extends SQLiteOpenHelper
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "ITStock";
private static final String TABLE_STOCK = "stock";
private static final String KEY_ID = "id";
private static final String KEY_ITEM = "item";
private static final String KEY_CONDITION = "condition";
private static final String KEY_QUANTITY = "quantity";
private static final String KEY_LOCATION = "location";
private static final String KEY_CATEGORY = "category";
public DBHandler(Context context)
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// Creating Table
@Override
public void onCreate(SQLiteDatabase db)
String CREATE_STOCK_TABLE = "CREATE TABLE " + TABLE_STOCK + "(" + KEY_ID
+ " INTEGER PRIMARY KEY,"
+ KEY_ITEM + " TEXT,"
+ KEY_CONDITION + " TEXT,"
+ KEY_QUANTITY + " INT,"
+ KEY_LOCATION + " TEXT,"
+ KEY_CATEGORY + " TEXT" + ")";
db.execSQL(CREATE_STOCK_TABLE);
// Upgrading Database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_STOCK);
// Create tables again
onCreate(db);
// Get a single stock item
Stock getStockItem(int id)
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_STOCK, new String[] KEY_ID, KEY_ITEM, KEY_CONDITION, KEY_QUANTITY, KEY_LOCATION, KEY_CATEGORY, KEY_ID + "=?",
new String[] String.valueOf(id), null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
Stock stock = new Stock(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getInt(3),
cursor.getString(4), cursor.getString(5));
return stock;
// Get all stock items
public ArrayList<Stock> getAllStock()
String selectQuery = "SELECT * FROM " + TABLE_STOCK;
SQLiteDatabase db = this.getWritableDatabase();
ArrayList<Stock> stockList = new ArrayList<>();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst())
do
int id = Integer.parseInt(cursor.getString(0));
String item = cursor.getString(1);
String condition = cursor.getString(2);
int quantity = cursor.getInt(3);
String location = cursor.getString(4);
String category = cursor.getString(5);
stockList.add(new Stock(id, item, condition, quantity, location, category));
while (cursor.moveToNext());
cursor.close();
return stockList;
// Delete single stock item
public void deleteStockItem(Stock stock)
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_STOCK, KEY_ID + " = ?", new String[] String.valueOf(stock.getID()));
db.close();
Stock.java:
public class Stock
int id;
String item;
String condition;
int quantity;
String location;
String category;
public Stock()
public Stock(int id, String item, String condition, int quantity, String location, String category)
this.id = id;
this.item = item;
this.condition = condition;
this.quantity = quantity;
this.location = location;
this.category = category;
public Stock(String item, String condition, int quantity, String location, String category)
this.item = item;
this.condition = condition;
this.quantity = quantity;
this.location = location;
this.category = category;
// Getters and setters
public int getID()
return this.id;
public void setID(int id)
this.id = id;
public String getItem()
return this.item;
public void setItem(String item)
this.item = item;
public String getCondition()
return this.condition;
public void setCondition(String condition)
this.condition = condition;
public int getQuantity()
return this.quantity;
public void setQuantity(int quantity)
this.quantity = quantity;
public String getLocation()
return this.location;
public void setLocation(String location)
this.location = location;
public String getCategory()
return this.category;
public void setCategory(String category)
this.category = category;
StockAdapter.java:
public class StockAdapter extends RecyclerView.Adapter<StockAdapter.ViewHolder>
private Context context;
private ArrayList<Stock> listStock;
private ArrayList<Stock> mArrayList;
private DBHandler db;
private MainActivity mainActivity;
private StockViewInterface stockViewInterface;
StockAdapter(Context context, ArrayList<Stock> listStock, StockViewInterface stockViewInterface)
this.context = context;
this.listStock = listStock;
this.mArrayList = listStock;
this.stockViewInterface = stockViewInterface;
db = new DBHandler(context);
mainActivity = new MainActivity();
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View stockView = inflater.inflate(R.layout.stock_row, parent, false);
return new ViewHolder(stockView);
@Override
public void onBindViewHolder(ViewHolder holder, int position)
final Stock stock = listStock.get(position);
holder.tvItem.setText(stock.getItem());
holder.tvCondition.setText(stock.getCondition());
holder.tvQuantity.setText(String.valueOf(stock.getQuantity()));
holder.tvLocation.setText(stock.getLocation());
holder.tvCategory.setText(stock.getCategory());
@Override
public int getItemCount()
return listStock.size();
class ViewHolder extends RecyclerView.ViewHolder
final TextView tvItem;
final TextView tvCondition;
final TextView tvQuantity;
final TextView tvLocation;
final TextView tvCategory;
View stockView;
ViewHolder(View stockView)
super(stockView);
this.stockView = stockView;
stockView.setOnClickListener(v -> stockViewInterface.onItemClick(getAdapterPosition()));
stockView.setOnLongClickListener(v ->
stockViewInterface.onLongItemClick(getAdapterPosition());
return false;
);
tvItem = stockView.findViewById(R.id.tvItem);
tvCondition = stockView.findViewById(R.id.tvCondition);
tvQuantity = stockView.findViewById(R.id.tvQuantity);
tvLocation = stockView.findViewById(R.id.tvLocation);
tvCategory = stockView.findViewById(R.id.tvCategory);
我的 deleteStockItem 方法正在 MainActivity 中使用以下内容(1 是 ID 号):
db.deleteStockItem(db.getStockItem(1))
我不想手动输入 ID 号,所以它需要类似于
db.deleteStockItem(db.getStockItem(getID))
但我不知道该怎么做。 我试过这样做:
db.deleteStockItem(db.getStockItem(stock.getID()));
并得到这个错误:
E/androidRuntime: FATAL EXCEPTION: main
Process: com.example.it_stock, PID: 14325
android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:460)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.it_stock.DBHandler.getStockItem(DBHandler.java:71)
at com.example.it_stock.MainActivity.onLongItemClick(MainActivity.java:74)
at com.example.it_stock.StockAdapter$ViewHolder.lambda$new$1$StockAdapter$ViewHolder(StockAdapter.java:71)
at com.example.it_stock.-$$Lambda$StockAdapter$ViewHolder$glwJYV6g13zGeNPhabWeayxaKNY.onLongClick(lambda)
at android.view.View.performLongClickInternal(View.java:5714)
at android.view.View.performLongClick(View.java:5672)
at android.view.View.performLongClick(View.java:5690)
at android.view.View$CheckForLongPress.run(View.java:22402)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6121)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
【问题讨论】:
【参考方案1】:我认为这是因为您的 stock
对象中没有任何项目。
我检查了你的代码,你应该更新它
您应该在onBindViewHolder
函数中编写setOnLongClickListener
事件并将其从ViewHolder
函数中删除。
您的onBindViewHolder
将是这样的:
@Override
public void onBindViewHolder(ViewHolder holder, int position)
final Stock stock = listStock.get(position);
holder.tvItem.setText(stock.getItem());
holder.tvCondition.setText(stock.getCondition());
holder.tvQuantity.setText(String.valueOf(stock.getQuantity()));
holder.tvLocation.setText(stock.getLocation());
holder.tvCategory.setText(stock.getCategory());
stockView.setOnLongClickListener(v ->
stockViewInterface.onLongItemClick(position);
return false;
);
您的MainActivity.java
有一些变化:
public class MainActivity extends AppCompatActivity implements StockViewInterface
private DBHandler db;
// remove this you don't need it
//private Stock stock;
// set allStock global to be easy to use
private ArrayList<Stock> allStock = new ArrayList<Stock>();
// set your adapter here
private StockAdapter stockAdapter ;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView stockView = findViewById(R.id.rvStock);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
stockView.setLayoutManager(linearLayoutManager);
stockView.setHasFixedSize(true);
db = new DBHandler(this);
// remove this you don't need it
//stock = new Stock();
// here you can get list from db
allStock = db.getAllStock();
if (allStock.size() > 0)
stockView.setVisibility(View.VISIBLE);
stockAdapter = new StockAdapter(this, allStock, this);
stockView.setAdapter(stockAdapter);
else
stockView.setVisibility(View.GONE);
Toast.makeText(this, "No Items!", Toast.LENGTH_LONG).show();
@Override
public void onLongItemClick(int position)
Toast.makeText(this, "long pressed", Toast.LENGTH_SHORT).show();
// here you get id of the item you need to delete it
db.deleteStockItem(db.getStockItem(allStock.get(position).getID()));
// now you can delete the same item from your model
allStock.remove(position);
// update your view here
stockAdapter.notifyItemRemoved(position);
【讨论】:
谢谢 - 这已经奏效,我还必须添加 'stockAdapter = new StockAdapter(this, allStock, this);'所以它不是空的【参考方案2】:如果我正确理解了您的问题,我认为这种方法 在 MainActivity 中对你有用。
@Override
public void onLongItemClick(int position)
Toast.makeText(this, "long pressed", Toast.LENGTH_SHORT).show();
StockItem si = (StockItem) getItemAtPosition(position);
db.deleteStockItem(si.getId);
【讨论】:
您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。 您是在调用 Stock 类“StockItem”吗?如果是这样,对不起,这没有奏效。 stockView.setOnLongCklickListener(this);以上是关于如何使用 Recycler View 的长按位置获取 SQLite 列值?的主要内容,如果未能解决你的问题,请参考以下文章
如何使 Recycler View 表现得像 PlayStore Recycler Views
使用 Recycler View 将房间数据库滚动到特定位置