How do I load a SQlite Database into Recyclerview? - java

I have a recyclerview inside a fragment activity that uses a button to bring up an alert dialog box to get input for 2 string variables. I have successfully created the database and can add items to the database from the alertdialog input, but I want to populate the recyclerview with the database when the app initially starts up. The database is used to store the input and I want it to populate the recyclerview so the user can see the items they entered previously.
This is my fragment:
public class tab1Expenses extends Fragment {
SqlDatabase dbEntry;
ArrayList<ExRow> expenseList = new ArrayList<>();
RecyclerView recyclerView;
ExpensesAdapter mAdapter;
Button btnEx;
String Na;
String Am;
String message = "Name must be longer than 2 characters";
String message2 = "Please enter valid amount";
Double value;
String am;
public void expenseData() {
ExRow exs = new ExRow(Na, Am);
expenseList.add(exs);
mAdapter.notifyDataSetChanged();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final View rootView = inflater.inflate(R.layout.tab1expense, container, false);
btnEx = (Button) rootView.findViewById(R.id.btnEx);
recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
recyclerView.addItemDecoration(new DividerItemDecoration(tab1Expenses.this.getActivity(), LinearLayoutManager.VERTICAL));
mAdapter = new ExpensesAdapter(expenseList);
final RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this.getActivity());
recyclerView.setHasFixedSize(true);
recyclerView.setClickable(true);
recyclerView.isFocusable();
recyclerView.setFocusableInTouchMode(true);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
btnEx.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Brings up Alert Dialog when Add income button is pressed
add();
}
});
return rootView;
}
public int add() {
View view = LayoutInflater.from(tab1Expenses.this.getActivity())
.inflate(R.layout.add_ex, null);
final EditText txtExName = (EditText) view.findViewById(R.id.exName);
final EditText txtExAmount = (EditText) view.findViewById(R.id.exAmount);
//Creates Alert Dialog
AlertDialog.Builder add = new AlertDialog.Builder(tab1Expenses.this.getActivity());
add.setCancelable(true)
.setTitle("Enter Expense:")
.setView(view)
.setPositiveButton("Add",
//AlertDialog positive button ClickListener
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Checks for invalid input
//If criteria met, expenseData() is called
if (txtExAmount.getText().length() > 0 && txtExName.getText().length() > 2 && txtExAmount.getText().length() < 6 && txtExName.getText().length() < 25) {
Na = txtExName.getText().toString();
am = txtExAmount.getText().toString();
value = Double.parseDouble(am);
Am = NumberFormat.getCurrencyInstance().format(value);
expenseData();
}
//Toast for invalid input
if (txtExName.getText().length() <= 2) {
Toast.makeText(tab1Expenses.this.getActivity(), message, Toast.LENGTH_SHORT).show();
} else if (txtExAmount.getText().length() == 0) {
Toast.makeText(tab1Expenses.this.getActivity(), message2, Toast.LENGTH_SHORT).show();
} else if (txtExAmount.getText().length() >= 6) {
Toast.makeText(tab1Expenses.this.getActivity(), "You don't make that much", Toast.LENGTH_SHORT).show();
} else if (txtExName.getText().length() >= 25) {
Toast.makeText(tab1Expenses.this.getActivity(), "Name must be less than 25 characters", Toast.LENGTH_SHORT).show();
}
}
});
Dialog dialog = add.create();
dialog.show();
return 0;
}
public void viewAll() {
ExRow exrow = new ExRow();
Cursor res = dbEntry.getAllData();
exrow.setTitle(res.getString(1));
exrow.setAmount(res.getString(2));
}
}
This is my database:
public class SqlDatabase extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "Expenses.db";
public static final String TABLE_NAME = "Expense_Table";
public static final String ID = "id";
public static final String Col_NAME = "Na";
public static final String Col_AMOUNT = "Am";
public SqlDatabase(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
//Set up database here
public void onCreate(SQLiteDatabase db) {
db.execSQL("Create table " + TABLE_NAME +
"(ID INTEGER PRIMARY KEY AUTOINCREMENT,NAME TEXT, AMOUNT TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean insertData(String Na, String Am) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(Col_NAME, Na);
contentValues.put(Col_AMOUNT, Am);
long result = db.insert(TABLE_NAME, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
public static Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from " + TABLE_NAME, null);
return res;
}
}
And this is my RecyclerView Adapter + View holder:
public class ExpensesAdapter extends RecyclerView.Adapter<ExpensesAdapter.MyViewHolder> {
public ImageButton mRemoveButton;
private ArrayList<ExRow> expenseList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView title, amount;
public MyViewHolder(View view) {
super(view);
title = (TextView) view.findViewById(R.id.name);
amount = (TextView) view.findViewById(R.id.amount);
mRemoveButton = (ImageButton) view.findViewById(R.id.ib_remove);
}
}
public ExpensesAdapter(ArrayList<ExRow> expenseList) {
this.expenseList = expenseList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.expense_list, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position
) {
ExRow expense = expenseList.get(holder.getAdapterPosition());
holder.title.setText(expense.getTitle());
holder.amount.setText(expense.getAmount());
mRemoveButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// Remove the item on remove/button click
int adapterPosition = holder.getAdapterPosition();
expenseList.remove(adapterPosition);
notifyItemRemoved(adapterPosition);
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return expenseList.size();

You need to get List of your ExRow instead of cursor in your SQLiteOpenHelper. So instead of:
public static Cursor getAllData() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("select * from " + TABLE_NAME, null);
return res;
}
You need to return List with something like this:
// Your column
private String[] allColumns = { "ID", "COLUMN_1", "COLUMN_2" };
public List<ExRow> getAllData() {
List<ExRow> exrows = new ArrayList<>();
Cursor cursor = database.query("YOUR_TABLE", allColumns, null, null,
null, null, null);
if (cursor != null && cursor.moveToFirst()) {
while (!cursor.isAfterLast()) {
ExRow exrow = populateModel(cursor);
exrows.add(exrow);
cursor.moveToNext();
}
cursor.close();
}
return exrows;
}
private ExRow populateModel(Cursor c) {
ExRow model = new ExRow();
model.setId(c.getLong("ID"));
model.setColumn1(c.getString(c.getColumnIndex("COLUMN_1")));
model.setColumn2(c.getString(c.getColumnIndex("COLUMN_2")));
return model;
}
Then you can use the value returned from getAllData() and pass it to your Adapter.

Related

notifyDataSetChanged(); not updating my AdapterView

Instead a different activity for inserting the items I have a pop up that shows in the MainActivity so it doesnt refresh. I tried putting the notifyDataSetChanged() function in the onClickListiner of the button in the pop up but nothing.
RecyleView Adaper Code:
public class CustomAdapater extends RecyclerView.Adapter<CustomAdapater.MyViewHolder> {
Context context;
private ArrayList foodID, foodName, foodPrice;
CheckBox chkItem;
//Constructor
CustomAdapater(Context context, ArrayList foodID, ArrayList foodName, ArrayList foodPrice){
//Declares to global variables that can be used in the MainAcivity
this.context = context;
this.foodID = foodID;
this.foodName = foodName;
this.foodPrice = foodPrice;
}
#NonNull
#Override
public CustomAdapater.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//Inflates the item_row layout
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.item_row, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CustomAdapater.MyViewHolder holder, int position) {
holder.checkItem.setText(String.valueOf(" " + foodName.get(position)));
holder.foodPrice_txt.setText(String.valueOf(foodPrice.get(position) + "$"));
}
#Override
public int getItemCount() {
return foodID.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView foodPrice_txt;
CheckBox checkItem;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
checkItem = itemView.findViewById(R.id.chkItemRow);
foodPrice_txt = itemView.findViewById(R.id.txtPriceRow);
}
}
public void upDateData(){
notifyItemInserted(foodName.size());
notifyItemInserted(foodPrice.size());
notifyItemInserted(foodID.size());
}
}
MyDataBaseHelper.java
public class MyDataBaseHelper extends SQLiteOpenHelper {
private final Context context;
private static final String DATABASE_NAME = "FoodItem.db";
private static final int DATABASE_VERSION = 1;
//Declarations
public static final String TABLE_NAME = "my_food_items";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_FOOD_NAME = "food_name";
public static final String COLUMN_FOOD_PRICE = "food_price";
public MyDataBaseHelper(#Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
//Sql query
String query =
"CREATE TABLE " + TABLE_NAME +
" (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_FOOD_NAME + " TEXT, " +
COLUMN_FOOD_PRICE + " TEXT);";
db.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
void addFood(String name, String price){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_FOOD_NAME, name);
cv.put(COLUMN_FOOD_PRICE, price);
long result = db.insert(TABLE_NAME, null, cv);
//Checks if the items have been added
if(result == -1){
Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context,"Added Successfully!", Toast.LENGTH_SHORT).show();
}
}
Cursor readAllData(){
//Selects all the data from the sqlite table
String query = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = null;
//Checks if there is data in the table
if(db != null){
//Declares all the data from the table to cursors variable
cursor = db.rawQuery(query, null);
}
return cursor;
}
public void clearTable() {
SQLiteDatabase db = getWritableDatabase();
db.execSQL("DELETE FROM " + TABLE_NAME);
}
}
MainActivity code:
public class SecondScreen extends AppCompatActivity {
Button btnAddItem;
MyDataBaseHelper myDB;
ArrayList<String> foodID, foodName, foodPrice;
CustomAdapater customAdapater;
RecyclerView recyclerView;
//PopUp
EditText edtFoodName;
EditText edtFoodPrice;
Dialog myDialog;
Button btnAddFood;
TextView cancel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_screen);
//Declarations
txtSeekBarPercent = findViewById(R.id.txtSeekBarProcent);
seekBarTipPercent = findViewById(R.id.seekBarTipPercent);
txtItems = findViewById(R.id.txtItems);
btnRetakeImg = findViewById(R.id.btnRetake);
btnAddItem = findViewById(R.id.btnAddItem);
recyclerView = findViewById(R.id.recycleView);
myDB = new MyDataBaseHelper(SecondScreen.this);
foodID = new ArrayList<>();
foodName = new ArrayList<>();
foodPrice = new ArrayList<>();
//Button for adding items
btnAddItem.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popUp();
}
});
//Data from Sql Tables
storeDataInArrays();
customAdapater = new CustomAdapater(SecondScreen.this, foodID, foodName, foodPrice);
recyclerView.setLayoutManager(new LinearLayoutManager(SecondScreen.this));
recyclerView.setAdapter(customAdapater);
}
//Storing the data from the sql table
public void storeDataInArrays() {
Cursor cursor = myDB.readAllData();
//Gets the count of the rows
if (cursor.getCount() == 0) {
Log.i("TAG", "No data");
} else {
while (cursor.moveToNext()) {
foodID.add(cursor.getString(0));
foodName.add(cursor.getString(1));
foodPrice.add(cursor.getString(2));
}
}
}
public void popUp() {
myDialog = new Dialog(SecondScreen.this);
myDialog.setContentView(R.layout.add_food_popup);
myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
myDialog.getWindow().setLayout(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
myDialog.setCancelable(false);
myDialog.show();
edtFoodName = (EditText) myDialog.findViewById(R.id.edtFoodName);
edtFoodPrice = (EditText) myDialog.findViewById(R.id.edtFoodPrice);
btnAddFood = (Button) myDialog.findViewById(R.id.btnAddFood);
cancel = (TextView) myDialog.findViewById(R.id.popUpCancel);
btnAddFood.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyDataBaseHelper myDB = new MyDataBaseHelper(SecondScreen.this);
myDB.addFood(edtFoodName.getText().toString().trim(), edtFoodPrice.getText().toString().trim());
customAdaper.notifyDataSetChanged();
//Dismisses the popUP
myDialog.dismiss();
}
});
cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
myDialog.dismiss();
}
});
}
There are a few answers about this problem on here but none of them worked for my specific situation.
It is very hard to say what the problem actually is. The first thing I would advise you to do is to make a new class ex. Food with attributes foodID, foodName and foodPrice, and then make a single list of type Food, ex. ArrayList<Food> foodList which you will then pass to your adapter. Handling multiple lists in one adapter can cause different problems.

How to automatically update ListView with custom adapter when item is deleted from database

I created a ListView for which I implemented a custom adapter. Additionally I connected it to a SQLite database, which contains the content for the ListView.
I have one ListView with several items. Every item consists of a TextView and an ImageView which functions as a button. When the user clicks the ImageView, I want to delete the item from the database and automatically update the ListView.
Unluckily, I just know how to delete the item from the database. I can't think of a way to automatically update the ListView in my program, after the item got deleted from the database.
In the version below, I added an onItemClickListener for the ListView in the MainActivity - but it doesn't function for when the user clicks the ImageView (even though the ImageView is part of the ListView).
MainActivity
public class MainActivity extends AppCompatActivity {
//References to buttons and other controls on the layout
private Button btn_add;
private EditText et_todo;
private Switch sw;
private static ListView lv;
private static DataAdapter todoAdapter;
private DataBaseHelper dbHelper;
/**
* Initialization Method
*
* #param savedInstanceState
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new DataBaseHelper(MainActivity.this);
assignVariables();
registerClick();
showAllToDos(dbHelper);
}
private void assignVariables() {
//assign values to variables
btn_add = (Button) findViewById(R.id.btn_add);
et_todo = (EditText) findViewById(R.id.et_todo);
lv = (ListView) findViewById(R.id.lv);
}
public void showAllToDos(DataBaseHelper dbHelper) {
todoAdapter = new DataAdapter(MainActivity.this, R.layout.list_item, dbHelper.getAllAsList(), dbHelper);
lv.setAdapter(todoAdapter);
}
private void registerClick() {
btn_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String toDoTitle = et_todo.getText().toString();
if(Pattern.matches("s*", toDoTitle)) {
Toast.makeText(MainActivity.this, "Title is missing", Toast.LENGTH_SHORT).show();
} else if(dbHelper.existsInDB(new DataModel(toDoTitle))) {
Toast.makeText(MainActivity.this, "Already added as ToDo", Toast.LENGTH_SHORT).show();
} else {
DataModel dModel = new DataModel(toDoTitle);
dbHelper.addOne(dModel);
showAllToDos(dbHelper);
}
//empty input field
et_todo.setText("");
}
});
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
DataModel clickedItem = (DataModel) adapterView.getItemAtPosition(position);
dbHelper.deleteOne(clickedItem);
showAllToDos(dbHelper);
}
});
}
}
DataModel
public class DataModel {
//Attributes
private int id;
private String title;
//Constructors
public DataModel(String title) {
this.title = title;
}
public DataModel() {
}
//toString
#Override
public String toString() {
return "DataModel{" +
"id=" + id +
", title='" + title + '\'' +
'}';
}
//Getters and Setters
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
DataAdapter
public class DataAdapter extends ArrayAdapter<DataModel> {
/**
* Attributes
*/
private Context mContext;
private int mResource;
private ArrayList<DataModel> mList;
private DataBaseHelper mDbHelper;
public DataAdapter(Context context, int resource, ArrayList<DataModel> list, DataBaseHelper dbHelper) {
super(context, resource, list);
mContext = context;
mResource = resource;
mList = list;
mDbHelper = dbHelper;
}
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//get the objects information
String title = getItem(position).getTitle();
//create object with the information
DataModel model = new DataModel(title);
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
//get TextViews
TextView tvTitle = (TextView) convertView.findViewById(R.id.task);
//set information to TextViews
tvTitle.setText(title);
//delete function
ImageView delView = (ImageView) convertView.findViewById(R.id.delView);
delView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mDbHelper.deleteOne(model);
}
});
return convertView;
}
}
DataBaseHelper
public class DataBaseHelper extends SQLiteOpenHelper {
public static final String TODO_TABLE = "TODO_TABLE";
public static final String COLUMN_ID = "ID";
public static final String COLUMN_TODO_TITLE = "TODO_TITLE";
private Context mContext;
public DataBaseHelper(#Nullable Context context) {
super(context, "todo.db", null, 1);
mContext = context;
}
/**
* Is called when the app requests or inputs new data.
*
* #param db
*/
#Override
public void onCreate(SQLiteDatabase db) {
String createTableStatement = "CREATE TABLE " + TODO_TABLE
+ " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_TODO_TITLE + " TEXT)";
db.execSQL(createTableStatement);
//create new Table
}
/**
* Called whenever the database version number changes.
* Prevents the previous apps from crashing.
*
* #param sqLiteDatabase
* #param i
* #param i1
*/
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
/**
* method to add new database entry
*
* #param dModel
* #return
*/
public boolean addOne(DataModel dModel) {
SQLiteDatabase db = this.getWritableDatabase(); //for insert actions
ContentValues cv = new ContentValues(); //Content values stores data in pairs
cv.put(COLUMN_TODO_TITLE, dModel.getTitle());
long insert = db.insert(TODO_TABLE, null, cv);
//clean up, close connection to database and cursor
db.close();
if(insert == -1) { //if insert is negative number than insert went wrong
return false;
} else { //if insert is positive number than insert succeeded
return true;
}
}
public boolean deleteOne(DataModel dModel) {
//if DataModel is found in the database, delete it and return true
//if it is not found, return false
SQLiteDatabase db = this.getWritableDatabase();
String queryString = "DELETE FROM " + TODO_TABLE
+ " WHERE " + COLUMN_TODO_TITLE + " = " + "\"" + dModel.getTitle() + "\"";;
Cursor cursor = db.rawQuery(queryString, null);
if(cursor.moveToFirst()) {
return true;
} else {
return false;
}
}
public ArrayList<DataModel> getAllAsList() {
//create empty list
ArrayList<DataModel> returnList = new ArrayList<>();
//get data from the database
String queryString = "SELECT * FROM " + TODO_TABLE;
SQLiteDatabase db = this.getReadableDatabase(); //get data from database
Cursor cursor = db.rawQuery(queryString, null);
if(cursor.moveToFirst()) { //returns a true if there were items selected
//loop through results, create new todo objects, put them into return list
do {
String todoTitle = cursor.getString(1);
DataModel newTodo = new DataModel(todoTitle);
returnList.add(newTodo);
} while(cursor.moveToNext());
} else { //returns a false if no items were selected
//failure, to not add anything to the list
}
//clean up, close connection to database and cursor
cursor.close();
db.close();
return returnList;
}
public boolean existsInDB(DataModel dModel) {
SQLiteDatabase db = this.getWritableDatabase(); //for insert actions
String queryString = "SELECT * FROM " + TODO_TABLE
+ " WHERE " + COLUMN_TODO_TITLE + " = " + "\"" + dModel.getTitle() + "\"";
Cursor cursor = db.rawQuery(queryString, null);
if(cursor.moveToFirst()) {
return true;
} else {
return false;
}
}
}
I appreciate any kind of help or suggestion.
Let me know, if you need further explanation.
Nicole
In the version below, I added an onItemClickListener for the ListView in the MainActivity - but it doesn't function for when the user clicks the ImageView (even though the ImageView is part of the ListView).
Consider the following based upon your code:-
Working Example
The following code is based upon yours BUT with various changes that does delete and refresh the list when the image (purple box is clicked).
The list_item.xml layout (altered to highlight the items as no image):-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#color/teal_200">
<TextView
android:id="#+id/task"
android:layout_width="400dp"
android:layout_height="match_parent"
>
</TextView>
<ImageView
android:id="#+id/delView"
android:layout_width="100dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:background="#color/purple_200"
>
</ImageView>
</LinearLayout>
The DataModel class is unchanged.
The DatabaseHelper class has been changed to a) not close the database (this is inefficient as it will apply the WAL changes and then have to subseuqently open the databaset which is relatively resource costly) and b) to close all cursors when done with the and c) utilise the convenience methods :-
public class DataBaseHelper extends SQLiteOpenHelper {
public static final String TODO_TABLE = "TODO_TABLE";
public static final String COLUMN_ID = "ID";
public static final String COLUMN_TODO_TITLE = "TODO_TITLE";
private Context mContext;
public DataBaseHelper(#Nullable Context context) {
super(context, "todo.db", null, 1);
mContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTableStatement = "CREATE TABLE " + TODO_TABLE
+ " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_TODO_TITLE + " TEXT)";
db.execSQL(createTableStatement);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
public boolean addOne(DataModel dModel) {
SQLiteDatabase db = this.getWritableDatabase(); //for insert actions
ContentValues cv = new ContentValues(); //Content values stores data in pairs
cv.put(COLUMN_TODO_TITLE, dModel.getTitle());
return db.insert(TODO_TABLE, null, cv) > -1;
}
public boolean deleteOne(DataModel dModel) {
SQLiteDatabase db = this.getWritableDatabase();
return db.delete(TODO_TABLE,COLUMN_TODO_TITLE +"=?",new String[]{dModel.getTitle()}) > 0;
}
#SuppressLint("Range")
public ArrayList<DataModel> getAllAsList() {
//create empty list
ArrayList<DataModel> returnList = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TODO_TABLE,null,null,null,null,null,null);
while (cursor.moveToNext()) {
returnList.add(new DataModel(cursor.getString(cursor.getColumnIndex(COLUMN_TODO_TITLE))));
}
cursor.close();
return returnList;
}
public boolean existsInDB(DataModel dModel) {
boolean rv = false;
SQLiteDatabase db = this.getWritableDatabase(); //for insert actions
Cursor cursor = db.query(TODO_TABLE,null,COLUMN_TODO_TITLE+"=?",new String[]{dModel.getTitle()},null,null,null);
if(cursor.moveToFirst()) {
rv = true;
}
cursor.close();
return rv;
}
}
DataAdapter
public class DataAdapter extends ArrayAdapter<DataModel> {
/**
* Attributes
*/
private Context mContext;
private int mResource;
private ArrayList<DataModel> mList;
private DataBaseHelper mDbHelper;
public DataAdapter(Context context, int resource, ArrayList<DataModel> list, DataBaseHelper dbHelper) {
super(context, resource, list);
mContext = context;
mResource = resource;
mList = list;
mDbHelper = dbHelper;
}
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
//get the objects information
String title = getItem(position).getTitle();
//create object with the information
DataModel model = new DataModel(title);
LayoutInflater inflater = LayoutInflater.from(mContext);
convertView = inflater.inflate(mResource, parent, false);
//get TextViews
TextView tvTitle = (TextView) convertView.findViewById(R.id.task);
//set information to TextViews
tvTitle.setText(title);
//delete function
ImageView delView = (ImageView) convertView.findViewById(R.id.delView);
delView.setTag(position); //<<<<< ADDDED Sets the tag with the position in the list
delView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Integer position = new Integer(view.getTag().toString()); // gets the position from the tag
DataModel model = mList.get(position); // gets the respective DataModel from the ArrayList
Toast.makeText(view.getContext(),"You clicked the Image for Title = " + model.getTitle() + " position " + view.getTag(),Toast.LENGTH_SHORT).show();
Log.d("CLICKACTION","Image clicked for title = " + model.getTitle() + " position " + view.getTag());
/* probably faster but the potential for issues if for some reason deletes other than expected
if (mDbHelper.deleteOne(model)) {
mList.remove(model);
notifyDataSetChanged();
}
*/
/* Alternative approach - more intensive but the resultant list IS accurate */
mDbHelper.deleteOne(model);
ArrayList<DataModel> newlist = mDbHelper.getAllAsList();
mList.clear();
for (DataModel dm: newlist) {
mList.add(dm);
notifyDataSetChanged();
}
}
});
return convertView;
}
}
NOTE an important aspect is utilising the tag to tie the clicked view to the Todo/DataModel.
NOTE another important factor is the manipulation of the DataAdapter's instance of the ArrayList and the subsequent notifyDatasetChanged that tells the adapter to rebuild.
and MainActivity :-
public class MainActivity extends AppCompatActivity {
//References to buttons and other controls on the layout
private Button btn_add;
private EditText et_todo;
private Switch sw;
private static ListView lv;
private static DataAdapter todoAdapter;
private DataBaseHelper dbHelper;
/**
* Initialization Method
*
* #param savedInstanceState
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new DataBaseHelper(MainActivity.this);
assignVariables();
registerClick();
showAllToDos(dbHelper); // creates a new instance of the adapter each time it is called
}
private void assignVariables() {
//assign values to variables
btn_add = (Button) findViewById(R.id.btn_add);
et_todo = (EditText) findViewById(R.id.et_todo);
lv = (ListView) findViewById(R.id.lv);
}
public void showAllToDos(DataBaseHelper dbHelper) {
todoAdapter = new DataAdapter(MainActivity.this, R.layout.list_item, dbHelper.getAllAsList(), dbHelper);
lv.setAdapter(todoAdapter);
}
private void registerClick() {
btn_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String toDoTitle = et_todo.getText().toString();
if(Pattern.matches("s*", toDoTitle)) {
Toast.makeText(MainActivity.this, "Title is missing", Toast.LENGTH_SHORT).show();
} else if(dbHelper.existsInDB(new DataModel(toDoTitle))) {
Toast.makeText(MainActivity.this, "Already added as ToDo", Toast.LENGTH_SHORT).show();
} else {
DataModel dModel = new DataModel(toDoTitle);
dbHelper.addOne(dModel);
showAllToDos(dbHelper);
}
//empty input field
et_todo.setText("");
}
});
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Toast.makeText(view.getContext(),"Item was clicked for Title = " + ((DataModel) adapterView.getItemAtPosition(position)).getTitle(),Toast.LENGTH_SHORT).show();
Log.d("CLICKACTION","Item was clicked for Title" + ((DataModel) adapterView.getItemAtPosition(position)).getTitle());
//DataModel clickedItem = (DataModel) adapterView.getItemAtPosition(position);
//dbHelper.deleteOne(clickedItem);
//showAllToDos(dbHelper);
}
});
}
}
*Results
From a new install (empty Database) then the following actions were taken:-
Add Test001 - Test006 so :-
Click on Item Test003 (NOT the purple box (image))
Toast displays as expected.
Log includes D/CLICKACTION: Item was clicked for TitleTest003
Click on the Delete image (purple box) for Test003
Toast displays as expected Test003 position 2
Log includes D/CLICKACTION: Image clicked for title = Test003 position 2
i.e. Test003 removed from the display
Database via App Inspection shows:-
i.e. no Test003 row in the database
Using SQLite directly can be challenging, also ListView is outdated not recommended to use anymore. The best practise is to use RecycleView
Here is a good tutorial how to use it all:
Room - wrapper library for SQLite from Google
LiveData - for subscribing for live update
RecyclerView - UI widget for building efficient lists

How can ı update items position in SQliteopenhelper

I save my recyclerview with SQliteopenhelper . I use Itemtouchhelper and I can change items positions with itemtouchhelper on recycler view but I cant update positions on my database How Can I ?
todoactivity.java
public class todoactivity extends AppCompatActivity {
TextView title;
ImageButton gorevo;
RecyclerView recyclerView;
List<String>Listsx = new ArrayList<>();
TodoActivityAdpter adapterx;
DatabaseHelper4 myDBxxx;
TextView textView;
CheckBox checkBox;
long id;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_todoactivity);
recyclerView=findViewById(R.id.recyclerviewxx);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapterx=new TodoActivityAdpter(Listsx);
recyclerView.setAdapter(adapterx);
title=findViewById(R.id.titlex);
textView=findViewById(R.id.text_viewx);
gorevo = findViewById(R.id.gorevo);
myDBxxx = new DatabaseHelper4(this);
Cursor datax = myDBxxx.getListContents();
if(datax.getCount() == 0){
}else{
while(datax.moveToNext()){
Listsx.add(datax.getString(1));
ListAdapter listAdapterx = new ArrayAdapter<>(this,R.layout.todoactivity_item,R.id.textitem,Listsx);
adapterx.notifyItemInserted(Listsx.size()-1);
}
}
gorevo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(todoactivity.this);
bottomSheetDialog.setContentView(R.layout.bottomsheetlayout3);
bottomSheetDialog.show();
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
EditText editText = bottomSheetDialog.findViewById(R.id.editx);
Button ekle = bottomSheetDialog.findViewById(R.id.ekle);
ekle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String text = editText.getText().toString();
Listsx.add(text);
AddDataxxx(text);
adapterx.notifyItemInserted(Listsx.size()-1);
bottomSheetDialog.hide();
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),0);
}
});
}
});
back=findViewById(R.id.back);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(todoactivity.this, pomodoroscreen.class);
startActivity(i);
overridePendingTransition(0,0);
}
});
ItemTouchHelper.SimpleCallback move = new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.START | ItemTouchHelper.END , 0) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
Collections.swap(Listsx,fromPosition,toPosition);
recyclerView.getAdapter().notifyItemMoved(fromPosition,toPosition);
// I want update items position on my SQliteOpenhelper in there
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
}
};
ItemTouchHelper itemTouchHelperx = new ItemTouchHelper(move);
itemTouchHelperx.attachToRecyclerView(recyclerView);
}
public void AddDataxxx(String newEntry) {
boolean insertDatax = myDBxxx.addDataxxx(newEntry);
}
}
DatabaseHelper.java
public class DatabaseHelper4 extends SQLiteOpenHelper {
public static final String DATABASE_NAME4 = "mylistxxx.db";
public static final String TABLE_NAME4 = "mylist_dataxxx";
public static final String COL14 = "iDxxx";
public static final String COL24 = "ITEM1xxx";
public DatabaseHelper4(Context context) {
super(context, DATABASE_NAME4, null, 1);
}
#Override
public void onCreate(SQLiteDatabase dbxxx) {
String createTable = "CREATE TABLE " + TABLE_NAME4 + " (iDxxx INTEGER PRIMARY KEY AUTOINCREMENT, " +
" ITEM1xxx TEXT)";
dbxxx.execSQL(createTable);
}
#Override
public void onUpgrade(SQLiteDatabase dbxxx, int oldVersion, int newVersion) {
dbxxx.execSQL("DROP IF TABLE EXISTS " + TABLE_NAME4);
onCreate(dbxxx);
}
public boolean addDataxxx(String textt) {
SQLiteDatabase dbxxx = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL24, textt);
long result = dbxxx.insert(TABLE_NAME4, null, contentValues);
if (result == -1) {
return false;
} else {
return true;
}
}
public Cursor getListContents() {
SQLiteDatabase dbxxx = this.getWritableDatabase();
Cursor dataxxx = dbxxx.rawQuery("SELECT * FROM " + TABLE_NAME4, null);
return dataxxx;
}
}
Adapter.java
public class TodoActivityAdpter extends RecyclerView.Adapter<TodoActivityAdpter.Holder> {
List<String>Listsx;
public TodoActivityAdpter(List<String>itemxxx){
this.Listsx = itemxxx;
}
#NonNull
#Override
public TodoActivityAdpter.Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.todoactivity_item,parent,false);
Holder holder = new Holder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull TodoActivityAdpter.Holder holder, int position) {
holder.textView.setText(Listsx.get(position));
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.checkBox.isChecked()) {
holder.textView.setTextColor(view.getResources().getColor(R.color.grey));
} else {
holder.textView.setTextColor(view.getResources().getColor(R.color.Color_black));
}
}
});
}
#Override
public int getItemCount() {
return Listsx.size();
}
public class Holder extends RecyclerView.ViewHolder {
CheckBox checkBox;
TextView textView;
List<String>Listsx;
RecyclerView recyclerView;
Context mContext;
public Holder(View view) {
super(view);
textView=view.findViewById(R.id.text_viewx);
checkBox=view.findViewById(R.id.checkbox);
recyclerView=view.findViewById(R.id.recyclerviewxx);
}
}
}
Thats my java classes . My activity is todoactivity . My SQliteopenhelper is DatabaseHelper.java . My Adapter is adapter.java . I can change items position on my recyclerview but ı cant update items position on my database . How can I
I suggest adding a column with the position to use for ordering.
Please close the cursor and return a list of objects. You can read your cursor using cursor.getString(cursor.getColumnIndex(colName)). Overriding close in your helper and closing the writableDatabase is also good practise. I myself open the writableDatabase only once (upon create) and close it at the end (upon close).
Regards, Mike

Recycler view show updated list only after launching activity once again

I have populated recyclerview from sqlite .when clicking delete button, row will delete from sqlite and when click on edit button value updated from sqlite but recyclerview not showing updated list after delete or edit. Recycler view show updated list only after launching activity once again. My question is how to update the recycler view soon after deleting or updating an item from the recylcerview without refresh.
Fragment code where i use recyclerview:
List<Product> productList = new ArrayList<>();
RecyclerView recyclerView;
SQLiteDatabase mDatabase;
public static ProductAdapter adapter;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
saveViewModel = ViewModelProviders.of(this).get(SaveViewModel.class);
View root = inflater.inflate(R.layout.fragment_save, container, false);
/* final TextView textView = root.findViewById(R.id.text_gallery);*/
recyclerView = root.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mDatabase = getActivity().openOrCreateDatabase(Add_Activity.DATABASE_NAME, MODE_PRIVATE, null);
showDataFromDatabase();
saveViewModel.getText().observe(getActivity(), new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
/* textView.setText(s);*/
}
});
return root;
}
private void showDataFromDatabase() {
//we used rawQuery(sql, selectionargs) for fetching all the fields
Cursor cursorproduct = mDatabase.rawQuery(" SELECT * FROM items", null);
//if the cursor has some data
if (cursorproduct.moveToFirst()) {
//looping through all the records
do {
//pushing each record in the field list
productList.add(new Product(
cursorproduct.getInt(0),
cursorproduct.getString(1),
cursorproduct.getString(2),
cursorproduct.getString(3),
cursorproduct.getString(4),
cursorproduct.getString(5),
));
} while (cursorproduct.moveToNext());
}
if (productList.isEmpty()) {
Toast.makeText(getActivity(), "No items Found in database", Toast.LENGTH_SHORT).show();
}
//closing the cursor
cursorproduct.close();
//creating the adapter object
adapter = new ProductAdapter(getActivity(), R.layout.show_field_items, productList, mDatabase);
//adding the adapter to listview
recyclerView.setAdapter(adapter);
adapter.reloadEmployeesFromDatabase(); //this method is in prdouctadapter
adapter.notifyDataSetChanged();
}
}
View model class:
public class Product {
private int id;
private String date;
private String category;
private String fsub_category;
private String fname;
private String fphone;
public Product(int id, String date, String category, String fsub_category, String fname, String fphone) {
this.id = id;
this.date = date;
this.category = category;
this.fsub_category =fsub_category;
this.fname = fname;
this.fphone = fphone;
}
public int getId() {
return id;
}
public String getFname() {
return fname;
}
public String getFcategory() {
return category;
}
public String getFsub_category() {
return fsub_category;
}
public String getFphone() {
return fphone;
}
public String getFdate() {
return date;
}
}
Product Adapter class:
public ProductAdapter(Context mCtx, int custom_list_item, List<Product> productList, SQLiteDatabase mDatabase) {
this.mCtx = mCtx;
this.custom_list_item = custom_list_item;
this.mDatabase = mDatabase;
this.productList = productList;
}
#NonNull
#Override
public ProductViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.show_field_items, null);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(ProductViewHolder holder, int position) {
//getting the product of the specified position
final Product product = productList.get(position);
//binding the data with the viewholder views
holder.Category.setText(product.getFcategory());
holder.Date.setText(product.getFdate());
holder.Area.setText(product.getFcategoty());
holder.editbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
updateEmployee(product);
}
});
holder.deletebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(mCtx);
builder.setTitle("Are you sure?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String sql = "DELETE FROM items WHERE id = ?";
mDatabase.execSQL(sql, new Integer[]{product.getId()});
Snackbar.make(view, "Deleted" + product.getFcategory(), Snackbar.LENGTH_SHORT).show();
Toast.makeText(mCtx, "Deleted successfully!", Toast.LENGTH_SHORT).show();
reloadEmployeesFromDatabase(); //Reload List
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
});
}
public void reloadEmployeesFromDatabase() {
Cursor cursorproduct1 = mDatabase.rawQuery("SELECT * FROM items", null);
if (cursorproduct1.moveToFirst()) {
productList.clear();
do {
productList.add(new Product(
cursorproduct1.getInt(0),
cursorproduct1.getString(1),
cursorproduct1.getString(2),
cursorproduct1.getString(3),
cursorproduct1.getString(4),
cursorproduct1.getString(5)
));
} while (cursorproduct1.moveToNext());
}
cursorproduct1.close();
notifyDataSetChanged();
}
private void updateEmployee(final Product product) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mCtx);
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.update_form, null);
builder.setView(view);
category = view.findViewById(R.id.spiner);
final EditText editsubcat= view.findViewById(R.id.editsubcategory);
final EditText editFname = view.findViewById(R.id.editFarmerName);
final EditText editphno = view.findViewById(R.id.editFarmerphno);
String cat = category.getSelectedItem().toString().trim();
editsubcat.setText(product.getFsub_category());
editFname.setText(product.getFname());
editphno.setText(product.getFphone());
final AlertDialog dialog = builder.create();
dialog.show();
// CREATE METHOD FOR EDIT THE FORM
view.findViewById(R.id.buttonUpdateEmployee).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String Crop = category.getSelectedItem().toString().trim();
String Sub_Category = editsubcat.getText().toString().trim();
String Farmer_Name = editFname.getText().toString().trim();
String Farmer_phone_No = editphno.getText().toString().trim();
/* if (Crop.isEmpty()) {
editTextName.setError("Name can't be blank");
editTextName.requestFocus();
return;
}
if (Sub_Category.isEmpty()) {
editUsername.setError("Salary can't be blank");
editUsername.requestFocus();
return;
}//Name, Email, UserName, PhoneNo*/
String sql = "UPDATE items \n" +
"SET Category = ?, \n" +
"Sub_Category = ?,\n" +
"Farmer_Name = ?,\n" +
"Farmer_phone_No= ? \n" +
"WHERE id = ?;\n";
mDatabase.execSQL(sql, new String[]{Crop,Sub_Category, Farmer_Name, Farmer_phone_No, String.valueOf(product.getId())});
Toast.makeText(mCtx, "data Updated", Toast.LENGTH_SHORT).show();
dialog.dismiss();
List<Product> pro = productList;
productList.clear();
productList.addAll(pro);
}
});
notifyDataSetChanged();
/* notifyItemRangeChanged(0, productList.size());*/
}
/* public void updateList(List<Product> itemList)
{
this.productList.clear();
this.productList.addAll(itemList);
notifyDataSetChanged();
}*/
/* private void updateList(List<Product> products) {
this.productList.clear();
this.productList.addAll(products);
productAdapter.notifyDataSetChanged();
}
*/
#Override
public int getItemCount() {
return productList.size();
}
public void setData(List<Product> items) {
productList = items;
}
class ProductViewHolder extends RecyclerView.ViewHolder {
TextView Date, Category, Area;
Button editbtn, deletebtn;
public ProductViewHolder(View itemView) {
super(itemView);
Category = itemView.findViewById(R.id.f_category);
Date = itemView.findViewById(R.id.f_date);
Area = itemView.findViewById(R.id.f_area);
}
}
}
After delete for update you need to update productList as well like :
holder.deletebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(mCtx);
builder.setTitle("Are you sure?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
String sql = "DELETE FROM items WHERE id = ?";
mDatabase.execSQL(sql, new Integer[]{product.getId()});
Snackbar.make(view, "Deleted" + product.getFcategory(), Snackbar.LENGTH_SHORT).show();
Toast.makeText(mCtx, "Deleted successfully!", Toast.LENGTH_SHORT).show();
//reloadEmployeesFromDatabase(); //Reload List
productList.remove(product); //like that after notify adapter
notifyDataSetchanged();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
});
in update you need to update product obj in productList :
String Crop = category.getSelectedItem().toString().trim();
String Sub_Category = editsubcat.getText().toString().trim();
String Farmer_Name = editFname.getText().toString().trim();
String Farmer_phone_No = editphno.getText().toString().trim();
// afer updating in sqlite db and also need to create setter in model
productList.get(position).setFcategory(Crop);
..........
//after pudating all feild like that just notify data set
notifyDataSetchanged();

Remove an item by clicking on image from the RecyclerView and SQLite database

I am creating a todo app with SQLite and RecyclerView, but I am having trouble in removing a task on a click of an image, which is my ivDelete. I want to delete completed tasks. any idea how to delete? any help would be appreciated.
This is my MainActivity:
public class MainActivity extends AppCompatActivity
{
Button btn_tasks,btn_reminders,btn_about;
ImageView img_addtask;
RecyclerView contactView;
DBHelper dbHelper;
CustomAdapter mAdapter;
private ArrayList<TaskClass> allContacts;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_tasks = findViewById(R.id.btn_task);
btn_reminders = findViewById(R.id.btn_reminder);
btn_about = findViewById(R.id.btn_about);
img_addtask = findViewById(R.id.imageView);
dbHelper = new DBHelper(this);
contactView = findViewById(R.id.list);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
contactView.setLayoutManager(layoutManager);
contactView.setHasFixedSize(true);
allContacts = new ArrayList<>();
allContacts = dbHelper.getTaskList();
loadTaskList();
img_addtask.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
addTask();
}
});
btn_reminders.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
addReminder();
}
});
}
private void loadTaskList()
{
ArrayList<TaskClass> taskList = dbHelper.getTaskList();
if(mAdapter == null)
{
contactView.setVisibility(View.VISIBLE);
mAdapter = new CustomAdapter(this,allContacts);
contactView.setAdapter(mAdapter);
}
else
{
contactView.setVisibility(View.GONE);
Toast.makeText(this, "There is no task in the database. Start
adding now", Toast.LENGTH_LONG).show();
}
}
private void addTask()
{
Intent intent = new Intent(this,AddTask.class);
startActivity(intent);
}
private void addReminder()
{
Intent intent = new Intent(this,AddReminder.class);
startActivity(intent);
}
}
This is my DBHelper Class:
public class DBHelper extends SQLiteOpenHelper
{
private static final String DB_NAME = "Demo.db";
private static final int DB_VER = 1;
private static final String DB_TABLE = "Task";
DBHelper(Context context)
{
super(context, DB_NAME, null, DB_VER);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(" CREATE TABLE " +DB_TABLE+" (ID INTEGER PRIMARY KEY AUTOINCREMENT, TaskName TEXT, dateStr TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1)
{
db.execSQL("DROP TABLE IF EXISTS "+DB_TABLE);
onCreate(db);
}
void insertNewTask(TaskClass taskClass)
{
ContentValues values = new ContentValues();
SQLiteDatabase db= this.getWritableDatabase();
values.put("TaskName",taskClass.getTaskName());
values.put("dateStr", taskClass.getTaskDate());
db.insert(DB_TABLE,null,values);
db.close();
}
public ArrayList<TaskClass> getTaskList()
{
String selectQuery = "SELECT * FROM " + DB_TABLE;
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<TaskClass> taskList = new ArrayList<>();
Cursor cursor = db.rawQuery(selectQuery, null);
if(cursor.moveToFirst())
{
do {
String name = cursor.getString(cursor.getColumnIndex("TaskName"));
String date = cursor.getString(cursor.getColumnIndex("dateStr"));
taskList.add(new TaskClass(name,date));
}while (cursor.moveToNext());
}
cursor.close();
return taskList;
}
}
This is CustomAdapter Class:
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull CustomViewHolder viewHolder, final int position)
{
viewHolder.txtTask.setText(taskClass.get(position).getTaskName());
viewHolder.txtDate.setText(taskClass.get(position).getTaskDate());
}
#Override
public int getItemCount() {
return taskClass.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder
{
TextView txtTask,txtDate;
ImageView ivDelete;
public CustomViewHolder(View itemView)
{
super(itemView);
txtTask = itemView.findViewById(R.id.task_title);
txtDate = itemView.findViewById(R.id.task_date);
ivDelete = itemView.findViewById(R.id.ivDelete);
}
}
You can put a listener on your ivDelete in the onBindViewHolder of the adapter, and
delete the task by the id from the database. You will have to create a method to do so on the DBHelper class.
viewHolder.ivDelete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Call method to delete task
}
});

Categories

Resources