SQLite Database - List all data from database with RecyclerView/adapter - android

i want to list all my stored data on database and show it on using a recycler view/adapter. Can anyone help me about this.
-i have a class of getter and setter(PWClass)
Here are some of my codes:
This is the time i am storing some data on class and add it on list but it is only a sample.
PWClass pwc = new PWClass("Facebook", "Action & Adventure", "2015");
pwList.add(pwc);
pwc = new PWClass("Instagram", "Action & Adventure", "2015");
pwList.add(pwc);
mAdapter.notifyDataSetChanged();
My problem is how can i combine the code above and calling a query on database to display datas like:
//i declare on top
private List<PWClass> pwList = new ArrayList<>();
private RecyclerView recyclerView;
private PWAdapter mAdapter;
Database controller;
//and from a method below
pwList.add(controller.add_pw());//adding on list array by calling my db method
Should i use some for/while loops/arrays? I am thinking the code above but i know its wrong. Do you get my point?
Please help so i can understand more, i appreciate your suggestions thanks!

read this post, you will get clear idea on Sqlite database.
check this out

public List<userData> getAlluser() {
List<userData> usersdetail = new ArrayList<>();
curser = dbs.query("data_table", null, null, null, null, null, null);
try {
if (curser.moveToFirst()) {
do {
userData muser = new userData();
muser.appname = curser.getString(curser.getColumnIndex("appname"));
muser.user = curser.getString(curser.getColumnIndex("email"));
muser.passwordss = curser.getString(curser.getColumnIndex("password"));
usersdetail.add(muser);
} while (curser.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
}
return usersdetail;
}
public class RecyclerViewAdopterMy extends RecyclerView.Adapter<RecyclerViewAdopterMy.MyViewHolder> implements View.OnClickListener {
List<userData> user = new ArrayList<>();
Context context;
public RecyclerViewAdopterMy(List<userData> user, Context context) {
this.user = user;
this.context = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, null);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.appR.setText(user.get(position).appname);
holder.nameR.setText(user.get(position).user);
holder.passR.setText(user.get(position).passwordss);
holder.cardR.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
AlertDialog.Builder alertbox = new AlertDialog.Builder(view.getRootView().getContext());
alertbox.setMessage("Do you want delete this item");
alertbox.setTitle("Delete");
alertbox.setIcon(R.drawable.delete);
alertbox.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
int pos = holder.getAdapterPosition();
user.remove(user.get(position));
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount());
notifyItemChanged(position);
}
});
alertbox.show();
return true;
}
});
}
#Override
public int getItemCount() {
return user.size();
}
#Override
public void onClick(View view) {
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
private final TextView appR;
private final TextView nameR;
private final TextView passR;
private final CardView cardR;
public MyViewHolder(View view) {
super(view);
appR = (TextView) view.findViewById(R.id.Appstore);
nameR = (TextView) view.findViewById(R.id.userStore);
passR = (TextView) view.findViewById(R.id.passstore);
cardR = (CardView) view.findViewById(R.id.card);
}
}
}

Related

App crash on last item deleted in RecyclerView

I'm using a RecyclerView and populating data from the database and storing it into arrayLists. i've also added an onLongClickListener() to the recycler view which removes the long clicked row. Everything works fine but when I delete the last the app crashes and i get Java.Lang.IndexOutOfBoundsException index:0 size:0.
here's my code
public class MainActivity extends AppCompatActivity implements AlarmRecyclerViewInterface {
FloatingActionButton mAlarmAddButton;
RecyclerView mRecyclerView;
SQLiteDatabase db;
AlarmsDBhelperClass mAlarmsDBhelperClass;
ArrayList<String> nameArrayList = new ArrayList<>();
ArrayList <String> modeArrayList = new ArrayList<>();
ArrayList<String> repeatArrayList = new ArrayList<>();
ArrayList<String> hoursArrayList = new ArrayList<>();
ArrayList<String> minArrayList = new ArrayList<>();
Switch mSwitch;
AlarmAdapter alarmAdapter = new AlarmAdapter(hoursArrayList,minArrayList,modeArrayList,repeatArrayList,nameArrayList,this);
ImageView emptyImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//Initializing RecyclerView, DatabaseHelperClass, FAB button, The ON OFF switch & the empty ImageView
mAlarmsDBhelperClass = new AlarmsDBhelperClass(getApplicationContext());
mAlarmAddButton = findViewById(R.id.btnAlarmADD);
mRecyclerView = findViewById(R.id.alarmList);
mSwitch = findViewById(R.id.switchONOFF);
emptyImageView = findViewById(R.id.empty_view);
//DividerItemDecoration class is used for getting a vertical line between rows of RecyclerView
DividerItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL);
mRecyclerView.addItemDecoration(itemDecoration);
//Getting a writable reference of the Database.
db = mAlarmsDBhelperClass.getWritableDatabase();
//Retrieving values from the database and storing them in custom ArrayLists
boolean isDataEmpty = getAlarm(db);
//Checking if our arrayList is empty? if yes then display some empty list text or an image
if (!isDataEmpty){
mRecyclerView.setVisibility(View.GONE);
emptyImageView.setImageResource(R.drawable.no_alarm_black_white);
emptyImageView.setVisibility(View.VISIBLE);
}
else {
mRecyclerView.setVisibility(View.VISIBLE);
emptyImageView.setVisibility(View.GONE);
}
//FAB Event handling
mAlarmAddButton.setImageResource(R.drawable.addalarm);
mAlarmAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent mIntent = new Intent(getApplicationContext(), AddAlarm.class);
startActivity(mIntent);
}
});
//Warping up with the recyclerView
mRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
mRecyclerView.setAdapter(alarmAdapter);
mRecyclerView.setHasFixedSize(true);
}
public boolean getAlarm(SQLiteDatabase db) {
Cursor cursor = db.rawQuery("SELECT * FROM alarms", new String[]{});
boolean rowExists;
if (cursor.moveToFirst()) {
do {
nameArrayList.add(cursor.getString(2));
modeArrayList.add(cursor.getString(3));
repeatArrayList.add(cursor.getString(4));
hoursArrayList.add(Integer.toString(cursor.getInt(5)));
minArrayList.add(Integer.toString(cursor.getInt(6)));
rowExists = true;
} while (cursor.moveToNext());
}else {
rowExists = false;
}
cursor.close();
return rowExists;
}
//RecyclerView's onClick()
#Override
public void onItemClick(int position) {
Toast.makeText(this, "Alarm Clicked !", Toast.LENGTH_SHORT).show();
}
//RecyclerView's onLongClick()
#Override
public void onLongItemClick(int position) {
hoursArrayList.remove(position);
//Updating the recyclerView
alarmAdapter.notifyItemRemoved(position);
//Deleting the row from the database
db.delete("alarms","hours=?",new String[]{hoursArrayList.get(position)});
Toast.makeText(this,"Alarm Deleted !", Toast.LENGTH_SHORT).show();
}
}
here's my RecyclerView Adapter
public class AlarmAdapter extends RecyclerView.Adapter<AlarmAdapter.AlarmView> {
//Variables for the main recycler view
private ArrayList<String> hoursArrayList;
private ArrayList<String> minArrayList;
private ArrayList<String> modeArrayList;
private ArrayList<String> repeatArrayList;
private ArrayList<String> nameArrayList;
private AlarmRecyclerViewInterface mInterface;
public AlarmAdapter(ArrayList<String> hours,ArrayList<String> mins,ArrayList<String> mode,ArrayList<String> repeat,ArrayList<String> name,AlarmRecyclerViewInterface mInterface){
this.hoursArrayList = hours;
this.minArrayList = mins;
this.modeArrayList = mode;
this.nameArrayList = name;
this.repeatArrayList = repeat;
this.mInterface = mInterface;
}
#NonNull
#Override
public AlarmView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.alarm_profile,parent,false);
return new AlarmView(view);
}
#Override
public void onBindViewHolder(#NonNull AlarmView holder, int position) {
if(Integer.parseInt(hoursArrayList.get(position)) < 10 ){
holder.hours.setText("0"+hoursArrayList.get(position));
}else {
holder.hours.setText(hoursArrayList.get(position));
}
if (Integer.parseInt(minArrayList.get(position)) < 10){
holder.mins.setText("0"+minArrayList.get(position));
}else {
holder.mins.setText(minArrayList.get(position));
}
holder.repeat.setText(repeatArrayList.get(position));
holder.mode.setText(modeArrayList.get(position));
holder.name.setText(nameArrayList.get(position));
}
#Override
public int getItemCount() {
return hoursArrayList.size();
}
/*ItemTouchHelper.SimpleCallback itemTouchHelperCallback = new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
nameArrayList.remove(viewHolder.getAdapterPosition());
modeArrayList.remove(viewHolder.getAdapterPosition());
repeatArrayList.remove(viewHolder.getAdapterPosition());
hoursArrayList.remove(viewHolder.getAdapterPosition());
minArrayList.remove(viewHolder.getAdapterPosition());
}
};*/
public class AlarmView extends RecyclerView.ViewHolder{
TextView hours,mins,repeat,name,mode;
public AlarmView(#NonNull View itemView) {
super(itemView);
hours = itemView.findViewById(R.id.txtHOUR);
mins = itemView.findViewById(R.id.txtMins);
repeat = itemView.findViewById(R.id.txtRepeatDays);
name = itemView.findViewById(R.id.txtName);
mode = itemView.findViewById(R.id.txtMode);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mInterface.onItemClick(getAdapterPosition());
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
mInterface.onLongItemClick(getAdapterPosition());
return true;
}
});
}
}
}
Thanks for the help!
Crash :- IndexOutOfBoundsException
Reason :- You removed data from the list and after that, you again fetching this value from the list to remove data from the database at that time it will crash because it has no value as you deleted data.
Solution :- You can delete first from the database and after that remove from your list.
Example :-
Replace below onLongClick() Override method in your class.
//RecyclerView's onLongClick()
#Override
public void onLongItemClick(int position) {
// Best way to remove data from list
if(hoursArrayList != null && hoursArrayList.size() > 0){
//Deleting the row from the database
db.delete("alarms","hours=?",new String[]{hoursArrayList.get(position)});
//Delete from your list if you successfully removed data from your database.
hoursArrayList.remove(position);
//Updating the recyclerView
if(alarmAdapter){
alarmAdapter.notifyItemRemoved(position);
}
//Message to show User.
Toast.makeText(this,"Alarm Deleted !", Toast.LENGTH_SHORT).show();
}
}

How Can Refresh RecyclerView Items After Update

I have a RecyclerView and I update the Data in the adapter, my problem is that After Change I can not refresh RecyclerView Data.
i used notifyDataSetChanged(); but is doesn't work
UpdateStudent edits the student name, the problem is that after the change, RecyclerView needs to refresh list
ReyclerView Adapter :
public class RecyclerViewAdapter_StudentList extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
List<StudentTable> tableData = new ArrayList<>();
Context context;
private LayoutInflater mInflater;
public RecyclerViewAdapter_StudentList(Context context, List<StudentTable> tableData) {
this.mInflater = LayoutInflater.from(context);
this.context = context;
this.tableData = tableData;
}
public class itemHolder extends RecyclerView.ViewHolder {
TextView studentName;
return new itemHolder(view);
}
}
onBindViewHolder
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
itemHolder itemHolder = (itemHolder) holder;
String studentName = tableData.get(position).getStudentName();
itemHolder.studentName.setText(studentName);
itemHolder.editStudent_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
String studentName_new = studentName_EditText.getText().toString();
database.UpdateStudent(classId , studentName_new);
notifyDataSetChanged();// does not work
}
}
}
Try this:
itemHolder.editStudent_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
String studentName_new = studentName_EditText.getText().toString();
database.UpdateStudent(classId , studentName_new);
StudentTable student = tableData.get(position);
student.setName(studentName_new);
tableData.set(position, student);
notifyItemChanged(position);
}
}
itemHolder.editStudent_Button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
String studentName_new = studentName_EditText.getText().toString();
database.UpdateStudent(classId , studentName_new);
StudentTable student = tableData.get(position);
student.setName(studentName_new);
notifyItemChanged(position);
}
}
Here you are notifying only adapter without changing data list so you need to do is
After updating retrieve data from table and store it in your current list tableData and then you have to call notifyDataSetChanged();

remove database item and update view on click

I am trying to remove item from database onClick of a button(defined as delbutton) here.
My Adapter looks like(I have included definitions and removed onBindViewHolder for brevity), and the onclick method is inside ViewHolder.
public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.ViewHolder> {
private static final String TAG = "PlaceAdapter";
List<PlaceSaved> items;
PlaceDatabase db;
public PlacesAdapter(List<PlaceSaved> items, PlaceDatabase db) {
this.items = items;
this.db = db;
}
#Override
public PlacesAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.places_list_item, parent, false);
return new ViewHolder(view);
}
#Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
public TextView name;
public TextView time;
public TextView longi;
public ImageButton delbutton;
public CardView cview;
public ViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.secondLine);
time = itemView.findViewById(R.id.firstLine);
longi = itemView.findViewById(R.id.longitude);
delbutton = itemView.findViewById(R.id.delicon);
cview = itemView.findViewById(R.id.place_view);
itemView.setOnClickListener(this);
delbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Log.e("What", "Get"+getAdapterPosition());
removeItem(getAdapterPosition());
}
});
}
#Override
public void onClick(View view) {
// Clicked postion
int position = getAdapterPosition();
PlaceSaved place = items.get(position);
// Here is the data Do your stuff
Log.e("Will WORK", place.getLongi());
}
}
private void removeItem(int position){
db.databaseInterface().delete(items.get(position));
items.remove(position);
notifyItemRemoved(position);
}
}
Now on clicking delbutton, I am getting the error:
java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
I know, I need to invoke runOnUIThread somehow, but inside ViewHolder, I cant define it. How can I solve this problem?
create new Thread Executors class like below
public class AppExecutors {
private final Executor mDiskIO;
private AppExecutors(Executor diskIO) {
this.mDiskIO = diskIO;
}
public AppExecutors() {
this(Executors.newSingleThreadExecutor());
}
public Executor diskIO() {
return mDiskIO;
}
}
use that class like this way..make return type of delete interface int type , to check successfully delete item.
private void removeItem(int position) {
new AppExecutors().diskIO().execute(new Runnable() {
#Override
public void run() {
if(db.databaseInterface().delete(items.get(position)) > 0 ){
runOnUiThread(new Runnable() {
#Override
public void run() {
items.remove(position);
notifyItemRemoved(position);
}
});
}
}
});
}

Cant realtime update recycleView whith realm

Sorry for my english. I have list objects, it list contains switch btn. When user change some switch i neeed it update in db. I
But when i try change swith, i have error:
java.lang.IllegalStateException: Cannot modify managed objects outside of a write transaction.
I can not understand how create adapter, who can update realtime data
My adapter:
public class DocumentTypeAdapterDB extends RealmRecyclerViewAdapter<DocType, DocumentTypeAdapterDB.ViewHolder> {
RealmList<DocType> docTypes;
public DocumentTypeAdapterDB(#Nullable RealmList<DocType> docTypes, Context context) {
super(docTypes, true);
this.docTypes = docTypes;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_doc_type, null);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutView.setLayoutParams(lp);
ViewHolder rcv = new ViewHolder(layoutView);
return rcv;
}
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
final DocType docType = docTypes.get(position);
holder.switch_item.setText(docType.name);
//check box
holder.switch_item.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!holder.switch_item.isChecked()) {
docType.is_check = false;
} else {
docType.is_check = true;
}
}
});
}
#Override
public int getItemCount() {
return docTypes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
SwitchCompat switch_item;
public ViewHolder(View itemView) {
super(itemView);
switch_item = (SwitchCompat) itemView.findViewById(R.id.switch_item);
}
public void clearAnimation()
{ itemView.clearAnimation(); }
}
}
DocType
public class DocType extends RealmObject{
public boolean is_check;
public String name;
//getter and setter
}
You need transaction to modify RealmObjects.
So, you should get Realm instance that docTypes belongs to and then:
realm.executeTransaction(new Realm.Transaction() {
#Override
public void execute(Realm realm) {
docType.is_check = holder.switch_item.isChecked();
}
});

android: Sort List after Adding items to the existing list using RecyclerView.Adapter

I have a RecyclerView which shows list of items sorted in descending order that works fine when I initially launch the screen, but when I add some more items to the existing list and setting it to the adapter with notifyDataSetChanged() method the existing list gets sorted in ascending order and the new items get added at the bottom of the view.
below is adapter
public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {
private List<Cinema> lists;
private int savedItems;
public RecycleAdapter(List<Cinema> cinemas, int savedItems) {
this.lists = cinemas;
this.savedItems = savedItems;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView cinemaTitle;
public TextView cinemaDescription;
public TextView cinemaDate;
public LinearLayout newLayout;
public ViewHolder(View view) {
super(view);
cinemaTitle = (TextView) view.findViewById(R.id.cinema_title);
cinemaDescription = (TextView) view.findViewById(R.id.description_text);
cinemaDate = (TextView) view.findViewById(R.id.cinema_date);
newLayout = (LinearLayout) view.findViewById(R.id.new_cinema_layout);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_cinema, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Cinema cinema = cinemas.get(position);
if (cinema.getId() > savedItems) {
holder.newLayout.setVisibility(View.VISIBLE);
} else {
holder.newLayout.setVisibility(View.INVISIBLE);
}
String title = cinema.getMessage().trim();
String description = cinema.getDescription().trim();
String date = cinema.getPublishedDate().trim();
holder.cinemaTitle.setText(title);
holder.cinemaDescription.setText(description);
holder.cinemaDate.setText(date);
}
public void setCineams(List<Cinema> cinemas) {
this.cinemas = cinemas;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return cinemas.size();
}
}
and the method which updates the list from Fragment is given below:
#Override
public void onCinemaUpdated() {
cinemas = firebaseHelper.getAllCinemas();
//Method which sorts the lists in descending order after adding new items into it
sortCinemas();
if (recycleAdapterAdapter != null) {
recycleAdapterAdapter.setCineams(cinemas);
}
}
I am not sure why am I getting this behaviour. Can anyone clarify on this?
Change your constructor and setCinemas method code to : Let me know if it helps..
public RecycleAdapter(List<Cinema> cinemas, int savedItems) {
this.lists = cinemas;
this.savedItems = savedItems;
}
public void setCineams(List<Cinema> cinemas) {
this.lists = cinemas;
notifyDataSetChanged();
}

Categories

Resources