I am trying to remove items from my SQLite table by long clicking on the row (will eventually use a button but just testing on long click for now). However I am struggling to delete the correct one. For context, when I add new rows to the table they get an ID number. Then I want to delete them using that ID number on long click. I've removed some code that isn't relevant below.
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);
}
}
}
My deleteStockItem method is working in MainActivity by using the below (1 being the ID number):
db.deleteStockItem(db.getStockItem(1))
I don't want to manually type the ID number though so it needs to be something like
db.deleteStockItem(db.getStockItem(getID))
But I'm not sure how to go about this. I tried doing this:
db.deleteStockItem(db.getStockItem(stock.getID()));
and get this error:
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)
CodePudding user response:
If I understood your question correctly, I think that this way the method in MainActivity would work for you.
@Override
public void onLongItemClick(int position) {
Toast.makeText(this, "long pressed", Toast.LENGTH_SHORT).show();
StockItem si = (StockItem) getItemAtPosition(position);
db.deleteStockItem(si.getId);
}
CodePudding user response:
I think this is because you don't have any item in your stock
object.
I checked your code and there is something's you should update it
- You should write the
setOnLongClickListener
event inonBindViewHolder
function and remove it fromViewHolder
function.
Your onBindViewHolder
will be like this :
@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;
});
}
- and there is some changes in your
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);
}
}