Using the Recyclerview with a Database

Using the recyclerview with a database

If you are running a query with a CursorLoader and you want RecyclerView instead of ListView.

You can try my CursorRecyclerViewAdapter: CursorAdapter in RecyclerView

Android Studio - Loading RecyclerView from SQLite Database entering a word in Edittext

Try to set attachToRoot in onCreateViewHolder to false

Will be:

 View contentView = LayoutInflater.from(parent.getContext()).inflate(R.layout.lista, false);

How to add data into SQLite database from recycler view in android studio

Try with the below query, It seems you are passing int value in status column.

   @Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(" CREATE TABLE " + TABLE_NAME + "(" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + Venue_name + " TEXT, " + Venue_type + " TEXT, " + Venue_budget + " TEXT, " + Venue_image + " TEXT, " + Venue_contact + " TEXT, " + FAV_STATUS + " INTEGER" + ")");

}

How to populate recyclerview from SQLite database

The Below Code is simple example of getting datas from Sqlite DB and showing it in a Recycler view

private List<Movie> movieList;
private RecyclerView mRecyclerView;
private MovieAdapter adapter;
private SQLiteHandler db;


Cursor cursor = db.getUserDetails();

if (cursor.moveToFirst()) {
do {
movieList.add(new Movie(
cursor.getInt(0),
cursor.getString(1),
cursor.getString(2),
cursor.getString(3),
cursor.getDouble(4)
));
} while (cursor.moveToNext());


MovieAdapter adapter = new MovieAdapter(this, movieList);
mRecyclerView.setAdapter(adapter);
}

How to implement searchview in recyclerview which based on SQLite? - Android

For Implementing search functionality in this project, as @thinkgruen suggested me that i need to work on single arraylist instead of multiple arraylist thats why i created separate class having all my data and made arraylist of that class, and implemented filter method to that arraylist.

After that i gone throgh this youtube tutorial - https://www.youtube.com/watch?v=CTvzoVtKoJ8

I'm posting changed code here, i made old code as a comment and changed code marked as //U . Beacuse U can clearly see what changes i have made.

at first here is new class - PatientList

package com.example.myclinic;

public class PatientList {

private int _id;
private String name;
private String disease;
private String medicine;
private long mobile;
private String address;
private int day;
private int month;
private int year;
private String serialid;


public int getid() {
return _id;
}
public void setid(int _id) {
this._id = _id;
}

public String getname() {
return name;
}
public void setname (String name) {
this.name = name;
}

public String getdisease() {
return disease;
}
public void setdisease (String disease) {
this.disease = disease;
}

public String getmedicine() {
return medicine;
}
public void setmedicine (String medicine) {
this.medicine = medicine;
}

public long getmobile() {
return mobile;
}
public void setmobile (long mobile) {
this.mobile = mobile;
}

public String getaddress() {
return address;
}
public void setaddress (String address) {
this.address = address;
}

public int getday() {
return day;
}
public void setday(int day) {
this.day = day;
}

public int getmonth() {
return month;
}
public void setmonth(int month) {
this.month = month;
}

public int getyear() {
return year;
}
public void setyear(int year) {
this.year = year;
}

public String getserialid() {
return serialid;
}
public void setserialid (String serialid) {
this.serialid = serialid;
}

//constructor
public PatientList(int _id, String name, String disease, String medicine, long mobile, String address, int day, int month, int year, String serialid){
this._id = _id;
this.name = name;
this.disease = disease;
this.medicine = medicine;
this.mobile = mobile;
this.address = address;
this.day = day;
this.month = month;
this.year = year;
this.serialid = serialid;
}

}

After that, in Class - CustomAdapter


package com.example.myclinic;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

//U
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> implements Filterable {

private Context context;
// private ArrayList _id, name, disease, medicine, mobile, address, day, month, year, serialid;
private List<PatientList> patientList = new ArrayList<>(); //U
private List<PatientList> patientListAll = new ArrayList<>();


CustomAdapter(Context context,/* ArrayList _id, ArrayList name, ArrayList disease,
ArrayList medicine, ArrayList mobile, ArrayList address, ArrayList day, ArrayList month, ArrayList year, ArrayList serialid, */
ArrayList<PatientList> patientList){
this.context = context;
/*
this._id = _id;
this.name = name;
this.disease = disease;
this.medicine = medicine;
this.mobile = mobile;
this.address = address;
this.day = day;
this.month = month;
this.year = year;
this.serialid = serialid;
*/

this.patientList = patientList; //U
this.patientListAll = new ArrayList<>(patientList);

}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.my_row, parent, false);
return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
/*
holder.id_txt.setText(String.valueOf(_id.get(position)));
holder.name_txt.setText(String.valueOf(name.get(position)));
holder.disease_txt.setText(String.valueOf(disease.get(position)));
holder.medicine_txt.setText(String.valueOf(medicine.get(position)));
holder.mobile_txt.setText(String.valueOf(mobile.get(position)));
holder.address_txt.setText(String.valueOf(address.get(position)));
holder.day_txt.setText(String.valueOf(day.get(position)));
holder.month_txt.setText(String.valueOf(month.get(position)));
holder.year_txt.setText(String.valueOf(year.get(position)));
holder.serialid_txt.setText(String.valueOf(serialid.get(position)));
*/

PatientList plist = patientList.get(position); //U
holder.id_txt.setText(String.valueOf(plist.getid()));
holder.name_txt.setText(String.valueOf(plist.getname()));
holder.disease_txt.setText(String.valueOf(plist.getdisease()));
holder.medicine_txt.setText(String.valueOf(plist.getmedicine()));
holder.mobile_txt.setText(String.valueOf(plist.getmobile()));
holder.address_txt.setText(String.valueOf(plist.getaddress()));
holder.day_txt.setText(String.valueOf(plist.getday()));
holder.month_txt.setText(String.valueOf(plist.getmonth()));
holder.year_txt.setText(String.valueOf(plist.getyear()));
holder.serialid_txt.setText(String.valueOf(plist.getserialid()));
}

@Override
public int getItemCount() {
return patientList.size();
}

//U
@Override
public Filter getFilter() {
return filter;
}
//U
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constaint) {

List<PatientList> filteredList = new ArrayList<>();

if (constaint.toString().isEmpty()) {
filteredList.addAll(patientListAll);
} else {
for (PatientList patient : patientListAll) {
if (patient.getname().toLowerCase().contains(constaint.toString().toLowerCase())
|| patient.getserialid().toLowerCase().contains(constaint.toString().toLowerCase())
|| patient.getaddress().toLowerCase().contains(constaint.toString().toLowerCase())) {
filteredList.add(patient);
}
}
}

FilterResults filterResults = new FilterResults();
filterResults.values = filteredList;
return filterResults;
}

@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
patientList.clear();
patientList.addAll((Collection<? extends PatientList>) filterResults.values);
notifyDataSetChanged();
}
};



public class MyViewHolder extends RecyclerView.ViewHolder {

TextView id_txt, name_txt, disease_txt, medicine_txt, mobile_txt, address_txt, day_txt, month_txt, year_txt, serialid_txt;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
id_txt = itemView.findViewById(R.id.id_txt);
name_txt = itemView.findViewById(R.id.name_txt);
disease_txt = itemView.findViewById(R.id.disease_txt);
medicine_txt = itemView.findViewById(R.id.medicine_txt);
mobile_txt = itemView.findViewById(R.id.mobile_txt);
address_txt = itemView.findViewById(R.id.address_txt);
day_txt = itemView.findViewById(R.id.day_txt);
month_txt = itemView.findViewById(R.id.month_txt);
year_txt = itemView.findViewById(R.id.year_txt);
serialid_txt = itemView.findViewById(R.id.serialid_txt);
}
}
}


Class DatabaseHelper

package com.example.myclinic;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.google.android.material.shape.ShapeAppearanceModel;

public class MyDatabaseHelper extends SQLiteOpenHelper {

private Context context;
private static final String DATABASE_NAME = "PatientList.db";
private static final int DATABASE_VERSION = 1;

private static final String TABLE_NAME = "patients";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_NAME = "name";
private static final String COLUMN_DISEASE = "disease";
private static final String COLUMN_MEDICINES = "medicines";
private static final String COLUMN_MOBILE = "mobile";
private static final String COLUMN_ADDRESS = "address";
private static final String COLUMN_DAY = "day";
private static final String COLUMN_MONTH = "month";
private static final String COLUMN_YEAR = "year";
private static final String COLUMN_SERIALID = "serialid";

public MyDatabaseHelper(@Nullable Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
}

@Override
public void onCreate(SQLiteDatabase db) {
String query =
"CREATE TABLE " + TABLE_NAME +
" (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_NAME + " TEXT, " +
COLUMN_DISEASE + " TEXT, " +
COLUMN_MEDICINES + " TEXT, " +
COLUMN_MOBILE + " INTEGER, " +
COLUMN_ADDRESS + " TEXT, " +
COLUMN_DAY + " INTEGER, " +
COLUMN_MONTH + " INTEGER, " +
COLUMN_YEAR + " INTEGER, " +
COLUMN_SERIALID + " TEXT);";
db.execSQL(query);

}

@Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}

void addPatient(String pname, String pdisease, String pmedicines, Long pmobile, String paddress, int pday, int pmonth, int pyear, String pserialid){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();

cv.put(COLUMN_NAME, pname);
cv.put(COLUMN_DISEASE, pdisease);
cv.put(COLUMN_MEDICINES, pmedicines);
cv.put(COLUMN_MOBILE, pmobile.longValue());
cv.put(COLUMN_ADDRESS, paddress);
cv.put(COLUMN_DAY, pday);
cv.put(COLUMN_MONTH, pmonth);
cv.put(COLUMN_YEAR, pyear);
cv.put(COLUMN_SERIALID, pserialid);
long result = db.insert(TABLE_NAME, null, cv);
if(result == -1) {
Toast.makeText(context, "Failed!", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(context, "Added Successfully...", Toast.LENGTH_SHORT).show();
}
}

Cursor readAllData(){
String query = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();

Cursor cursor = null;
if(db != null) cursor = db.rawQuery(query, null);
return cursor;
}

}

And Final changes in MainActivity.Java

package com.example.myclinic;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import androidx.appcompat.widget.SearchView;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import com.google.android.material.floatingactionbutton.FloatingActionButton;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

RecyclerView recyclerView;
FloatingActionButton add_button;

MyDatabaseHelper myDB;
// ArrayList<String> _id, name, disease, medicine, mobile, address, day, month, year, serialid;
ArrayList<PatientList> patientList = new ArrayList<>(); //U
CustomAdapter customAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

recyclerView = findViewById(R.id.recyclerView);
add_button = findViewById(R.id.add_button);
add_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivity(intent);
}
});

myDB = new MyDatabaseHelper(MainActivity.this);
/*
_id = new ArrayList<>();
name = new ArrayList<>();
disease = new ArrayList<>();
medicine = new ArrayList<>();
mobile = new ArrayList<>();
address = new ArrayList<>();
day = new ArrayList<>();
month = new ArrayList<>();
year = new ArrayList<>();
serialid = new ArrayList<>();
*/
storeDataInArray();

customAdapter = new CustomAdapter(MainActivity.this, patientList);
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
}

/*
void storeDataInArrays(){
Cursor cursor = myDB.readAllData();
if(cursor.getCount() == 0){
Toast.makeText(this, "No data.", Toast.LENGTH_SHORT).show();
}else{
while (cursor.moveToNext()){
_id.add(cursor.getString(0));
name.add(cursor.getString(1));
disease.add(cursor.getString(2));
medicine.add(cursor.getString(3));
mobile.add(String.valueOf(cursor.getLong(4)));
address.add(cursor.getString(5));
day.add(cursor.getString(6));
month.add(cursor.getString(7));
year.add(cursor.getString(8));
serialid.add(cursor.getString(9));

}
}
} */

void storeDataInArray(){ //U
Cursor cursor = myDB.readAllData();
if(cursor.getCount() == 0){
Toast.makeText(this, "No data.", Toast.LENGTH_SHORT).show();
}else{
while (cursor.moveToNext()){
patientList.add(new PatientList(cursor.getInt(0),
cursor.getString(1),
cursor.getString(2),
cursor.getString(3),
cursor.getLong(4),
cursor.getString(5),
cursor.getInt(6),
cursor.getInt(7),
cursor.getInt(8),
cursor.getString(9)));
}
}
}

@Override //U
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.mainmenu, menu);
MenuItem item = menu.findItem(R.id.action_search);

SearchView searchView = (SearchView)item.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}

@Override
public boolean onQueryTextChange(String newText) {
customAdapter.getFilter().filter(newText);
return false;
}
});

return super.onCreateOptionsMenu(menu);
}


}

nothing changed in AddActivity.
I hope this will be helpfull to you.

How to add & update data in SqliteDatabase by using RecyclerView Adapter

I believe the following will do as you wish.

The were quite a few issues with code. One of the major issues is that you expected the position to correlate with the id (aka your _id column).

The position of the first item in the list is 0, unless you force/specifically set the value of 0, an alias of the rowid column (your _id column is an alias of the rowid column), the first value assigned will be 1, then likely 2, then likely 3 ...........

So at best position will be 1 less than the id.

If a row is deleted, other than the last row then position will be one less except up until the deleted row is passed and then position will be 2 less than the rowid. More deletions and an even more complex correlation between position and id. I guess somebody could come up with a fool proof conversion BUT the simpe way is to ensure that the DataModel has the vale of the respective _id column.

As such DataModel.java should be changed to include a member/variable for the id therefore the following was used :-

public class DataModel {

public String FirstName;
public String LastName;
public String country;

public long id; //<<<<<<<<<< ADDED also added gettter and setter

public DataModel() {
}

public DataModel(String firstName, String lastName, String country) {
this(firstName,lastName,country,-1);
}

//<<<<<<<<<< ADDED so ID can be set
public DataModel(String firstName, String lastName, String country, long id) {
this.FirstName = firstName;
this.LastName = lastName;
this.country = country;
this.id = id;
}

public String getFirstName() {
return FirstName;
}

public void setFirstName(String firstName) {
FirstName = firstName;
}

public String getLastName() {
return LastName;
}

public void setLastName(String lastName) {
LastName = lastName;
}

public String getCountry() {
return country;
}

public void setCountry(String country) {
this.country = country;
}

public void setId(long id) {
this.id = id;
}

public long getId() {
return id;
}
}
  • see comments for changes

As you need to extract the id from the database, the object1 method was changed in DatabaseHelper.java (a few other changes have also been made) the following was used :-

public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "workers.db";
private static final int DATABASE_VERSION =7;

SQLiteDatabase db;

public DatabaseHelper( Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
db = this.getWritableDatabase();
}

@Override
public void onCreate(SQLiteDatabase db) {
this.db=db; //<<<<<<< WRONG PLACE as onCreate only ever runs when there is no database

final String SQL_CREATE_TBALE="CREATE TABLE " + DatabaseContractor.EmployeeDetails.TABLE_NAME + "(" + DatabaseContractor.EmployeeDetails._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+
DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME+" TEXT, "+ DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME+" TEXT, "+ DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY+" TEXT)";

db.execSQL(SQL_CREATE_TBALE);
fillquestion();
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + DatabaseContractor.EmployeeDetails.TABLE_NAME);
onCreate(db);
}


public void fillquestion(){
IntertData(new DataModel("Earth","Soil","B"));
IntertData(new DataModel("Sun","Light","B"));
IntertData(new DataModel("Moon","Rock","B"));
}

public void IntertData (DataModel data){

ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME,data.getFirstName());
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME,data.getLastName());
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY,data.country);
db.insert(DatabaseContractor.EmployeeDetails.TABLE_NAME,null,contentValues);
}

public List<DataModel> object1() {
ArrayList<DataModel> details = new ArrayList<>();
//db = getReadableDatabase(); db has already been set when database was instantiated/constructed
Cursor cursor = db.rawQuery("SELECT * FROM " + DatabaseContractor.EmployeeDetails.TABLE_NAME, null );
while (cursor.moveToNext()) {
details.add(new DataModel(
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_FIRSTNAME)),
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_LASTNAME)),
cursor.getString(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY)),
cursor.getLong(cursor.getColumnIndex(DatabaseContractor.EmployeeDetails._ID)) //<<<<<<<<< Added so id is available
));
}
cursor.close();
return details;
}
}

Pretty extensive changes were made to RecycAdapter.java, the following was used :-

public class RecycAdapter extends RecyclerView.Adapter<RecycAdapter.ViewHolder> {

List<DataModel> dotamodeldataArraylist;
Context context;
SQLiteDatabase db;
DatabaseHelper helper;
ContentValues contentValues;

public RecycAdapter(List<DataModel> dotamodeldataArraylist,Context context) {
this.dotamodeldataArraylist=dotamodeldataArraylist;
this.context=context;
helper = new DatabaseHelper(context);
db = helper.getWritableDatabase();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int ViewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlist,parent,false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final RecycAdapter.ViewHolder holder, final int position) {

//DataModel obj3= dotamodeldataArraylist.get(position); //<<<<<<<<<< NOT NEEDED
holder.Fnam.setText(dotamodeldataArraylist.get(position).getFirstName());
holder.Lname.setText(dotamodeldataArraylist.get(position).getLastName());
holder.Country.setText(dotamodeldataArraylist.get(position).getCountry());
holder.fav.setChecked(false); //<<<<<<<<< not stored so initially set to false

holder.fav.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String newcountry = "B";
if(holder.fav.isChecked()){
if (dotamodeldataArraylist.get(position).getCountry().equals("B")) {
newcountry = "A";
}
contentValues = new ContentValues();
contentValues.put(DatabaseContractor.EmployeeDetails.COLUMN_COUNTRY, newcountry);
if (db.update(
DatabaseContractor.EmployeeDetails.TABLE_NAME,
contentValues,
DatabaseContractor.EmployeeDetails._ID +"=?",
new String[]{String.valueOf(dotamodeldataArraylist.get(position).getId())}
) > 0) {
dotamodeldataArraylist.get(position).setCountry(newcountry);
notifyItemChanged(position);
Toast.makeText(context,
"checked and updated " +
position+ dotamodeldataArraylist.get(position).getFirstName() +
" ID is " + String.valueOf(dotamodeldataArraylist.get(position).getId()),
Toast.LENGTH_LONG
).show();
} else {
Toast.makeText(context,"error" + position , Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(context,"not checked" + position , Toast.LENGTH_LONG).show();
}
}
});
}

@Override
public int getItemCount() {
return dotamodeldataArraylist.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {

TextView Fnam,Lname,Country;
CheckBox fav;

public ViewHolder(View itemView) {
super(itemView);
Fnam = itemView.findViewById(R.id.name1);
Lname = itemView.findViewById(R.id.city1);
Country = itemView.findViewById(R.id.country1);
fav = itemView.findViewById(R.id.chk);
}
}
}

lastly a few minor changes were made to Viewall.java, the following was used :-

public class Viewall extends AppCompatActivity {

RecyclerView recyclerView;
DatabaseHelper databaseHelper;
RecycAdapter recycAdapter;
List<DataModel> dotamodeldataArraylist;
Button show;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewall);

show = findViewById(R.id.view);
recyclerView = findViewById(R.id.recycle);

databaseHelper = new DatabaseHelper(this);
dotamodeldataArraylist = databaseHelper.object1();
recycAdapter = new RecycAdapter(dotamodeldataArraylist, this);
RecyclerView.LayoutManager reLayoutManager = new
LinearLayoutManager(this);
recyclerView.setLayoutManager(reLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(recycAdapter);
}
}

Result

Note the layout(s) may be different, but your's should probably work and alter the presentation accordingly

When first run :-

After clicking the checkbox for Sun

Click again and back to Country B and so on.



Related Topics



Leave a reply



Submit