My data doesn't add to Recylerview after pressing the add button until I either restart the app or press the back button that's built in the action bar. My activity doesn't close after pressing the button so I usually use the back button on my device. Nothing gets added to my Recyclerview until the app restarts or when I add a new set of data and press the back button from the action bar, then 2 sets of data will be added.
I have also tried to finish the activity right after the button press but then that also doesn't add data into Recyclerview.
I want to know how I can make my activity finish after button press and display data in the Recyclerview or make it so that pressing the back button from my device still makes it display.
MainActivity Code:
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
FloatingActionButton newTaskBtn;
myDatabase myDB;
ArrayList<String> task_id, task_subject, task_description, task_due_date;
CustomAdapter customAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerTasks);
newTaskBtn = findViewById(R.id.floatingBtn);
newTaskBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddActivity.class);
startActivity(intent);
}
});
myDB = new myDatabase(MainActivity.this);
task_id = new ArrayList<>();
task_subject = new ArrayList<>();
task_description = new ArrayList<>();
task_due_date = new ArrayList<>();
storeDataArray();
customAdapter = new CustomAdapter(MainActivity.this, task_id, task_subject, task_description, task_due_date);
recyclerView.setAdapter(customAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
}
void storeDataArray() {
Cursor cursor = myDB.readAllData();
if (cursor.getCount() == 0) {
Toast.makeText(this, "No data", Toast.LENGTH_SHORT).show();
} else {
while (cursor.moveToNext()) {
task_id.add(cursor.getString(0));
task_subject.add(cursor.getString(1));
task_description.add(cursor.getString(2));
task_due_date.add(cursor.getString(3));
}
}
}
}
Add Data Activity Code:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
public class AddActivity extends AppCompatActivity {
EditText subjectEntry, descEntry, dateEntry;
Button addBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
subjectEntry = findViewById(R.id.subjectEntry);
descEntry = findViewById(R.id.descEntry);
dateEntry = findViewById(R.id.dateEntry);
addBtn = findViewById(R.id.addbtn);
addBtn.setOnClickListener(view -> {
myDatabase myDB = new myDatabase(AddActivity.this);
myDB.addTask(subjectEntry.getText().toString().trim(),
descEntry.getText().toString().trim(),
Integer.valueOf(dateEntry.getText().toString().trim()));
});
}
}
Adapter Code
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.myViewHolder> {
private Context context;
private ArrayList task_id, task_subject, task_description, task_due_date;
private int position;
CustomAdapter(Context context, ArrayList task_id, ArrayList task_subject, ArrayList task_description, ArrayList task_due_date){
this.context = context;
this.task_id = task_id;
this.task_description = task_description;
this.task_subject = task_subject;
this.task_due_date = task_due_date;
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from (context);
View view = inflater.inflate(R.layout.to_do_list, parent, false);
return new myViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final myViewHolder holder, final int position) {
this.position = position;
holder.taskid_txt.setText(String.valueOf(task_id.get(position)));
holder.taskSubject_txt.setText(String.valueOf(task_subject.get(position)));
holder.taskDescription_txt.setText(String.valueOf(task_description.get(position)));
holder.taskDate_txt.setText(String.valueOf(task_due_date.get(position)));
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra("id", String.valueOf(task_id.get(position)));
intent.putExtra("Description", String.valueOf(task_description.get(position)));
intent.putExtra("Subject", String.valueOf(task_subject.get(position)));
intent.putExtra("Due Date", String.valueOf(task_due_date.get(position)));
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return task_id.size();
}
public class myViewHolder extends RecyclerView.ViewHolder {
TextView taskid_txt, taskSubject_txt, taskDescription_txt, taskDate_txt;
LinearLayout mainLayout;
public myViewHolder(#NonNull View itemView) {
super(itemView);
taskid_txt = itemView.findViewById(R.id.taskid_txt);
taskSubject_txt = itemView.findViewById(R.id.taskSubject_txt);
taskDescription_txt = itemView.findViewById(R.id.taskDescription_txt);
taskDate_txt = itemView.findViewById(R.id.taskDate_txt);
mainLayout = itemView.findViewById(R.id.mainLayout);
}
}
;
}
Refresh recycle view in onResume of MainActivity
#Override
public void onResume() {
super.onResume();
storeDataArray();
}
Related
I try to create a Shopping/ToDoList application where the items are contained in SharedPreferences.
When I start the application, and I choose what I want to execute, Shopping list part or ToDoList part, then the java code fetches the existing data from the SharedPreferences and give to the RecycleView to create and show a list.
It seems works totally correct, but if I push the "add" button, then a new Activity is executed where I can specify the items, and when I click the save button, then the java code safe to the SharedPreferences and close the Activity and goes back to the "list" activity where the list should appears again with the new item. But when one data is inserted not in order in SharedPreferences but between two older data then the list create method get crazy and repeat always only the last data from SharedPreferences. But when I close the application, and restart, or goes back to the Main activity where I can choose again which list part I want then the list is totally OK again.
That is the list creating java code:
package com.example.recycleviewapp;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class ShoppingList extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener, View.OnClickListener {
public MyRecyclerViewAdapter adapter;
public Button btn;
public SharedPreferences sharedPreferences;
public SharedPreferences.Editor myEdit;
private List<String> items;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shoppinglist);
sharedPreferences = getSharedPreferences("ShoppingList", Context.MODE_PRIVATE);
myEdit = sharedPreferences.edit();
btn = findViewById(R.id.button);
items = new LinkedList<>();
StartDisplay();
RecyclerView recyclerView = findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
adapter = new MyRecyclerViewAdapter(this,items);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
btn.setOnClickListener(this);
}
#Override
public void onItemClick(View view, int position) {
//sharedPreferences = getSharedPreferences("ShoppingList", Context.MODE_PRIVATE);
String item_click =adapter.getItem(position);
String[] itemarray = item_click.split(" ",0);
//Toast.makeText(this, adapter.RemoveItem(position), Toast.LENGTH_SHORT).show();
//adapter.RemoveItem(position);
//myEdit = sharedPreferences.edit();
myEdit.remove(itemarray[0]);
myEdit.commit();
adapter.notifyItemRemoved(position);
items.remove(item_click);
}
#Override
public void onClick(View v) {
Intent NewSLItem = new Intent(ShoppingList.this, NewSLItem.class);
startActivity(NewSLItem);
}
#Override
public void onResume() {
super.onResume();
StartDisplay();
}
public void StartDisplay()
{
//sharedPreferences = getSharedPreferences("ShoppingList", Context.MODE_PRIVATE);
Map<String, ?> allEntries = sharedPreferences.getAll();
items.clear();
for (Map.Entry<String, ?> entry : allEntries.entrySet())
{
//Toast.makeText(this, entry.getKey(), Toast.LENGTH_SHORT).show();
String [] item_total = entry.getValue().toString().split(";");
items.add(entry.getKey() + " " + item_total[0] + " " + item_total[1]);
}
allEntries.clear();
}
}
Here is the code where I can specify the item:
package com.example.recycleviewapp;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class NewSLItem extends MainActivity {
private ArrayList<String> items;
private ArrayAdapter<String> itemsAdapter;
private ListView lvItems;
private Button btn;
public SharedPreferences sharedPreferences;
public SharedPreferences.Editor myEdit;
public List<String> list = new ArrayList<>();
public EditText etNewItem;
public String[] unit = {"liter", "kg", "pcs"};
public Spinner spinner;
public EditText amount;
public String itemName;
public TextView title;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shoppinglist_popup);
sharedPreferences = getSharedPreferences("ShoppingList", Context.MODE_PRIVATE);
myEdit = sharedPreferences.edit();
btn = (Button)findViewById(R.id.addbtn);
title = findViewById(R.id.title);
etNewItem = (EditText) findViewById(R.id.etNewItem);
amount = (EditText) findViewById(R.id.amount);
spinner = (Spinner) findViewById(R.id.spinner);
ArrayAdapter aa = new ArrayAdapter(this,android.R.layout.simple_spinner_item,unit);
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(aa);
title.setText("Create a new item for ShoppingList");
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
onAddItem();
finish();
}
});
}
public void onAddItem()
{
//myEdit = sharedPreferences.edit();
itemName = etNewItem.getText().toString();
String itemValue = amount.getText().toString() + ";" + spinner.getSelectedItem().toString();
myEdit.putString(itemName,itemValue);
myEdit.commit();
etNewItem.setText("");
}
}
and here is the RecyclerView code:
package com.example.recycleviewapp;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {
private List<String> mData;
private LayoutInflater mInflater;
private ItemClickListener mClickListener;
MyRecyclerViewAdapter(Context context, List<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String meta_data = mData.get(position);
if (meta_data.contains("High")) holder.myTextView.setBackgroundColor(Color.parseColor("#FF003B"));
holder.myTextView.setText(meta_data);
}
#Override
public int getItemCount() {
return mData.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.tvAnimalName);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view)
{
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
String getItem(int id) {return mData.get(id);
}
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
So the problem is in casef of only where the data is not in order in SharedPreferences and I go back from a new activity.
Please help me if you can, where should I fix my application?
Thanks in advance!!!
When you return to the list after adding an item, you reread all the items from the SharedPreferences in StartDisplay() (which is called from onResume(). This changes the data that the adapter is working with. However, you didn't tell the adapter that the data has changed. The adapter caches the Views and you must tell it when you modify the data, otherwise it doesn't know the data has changed. Add the following to StartDisplay() which will invalidate the adapter's cache and ensure that it rebuilds all the views:
adapter.notifyDataSetChanged()
Thank you for your help! It works.
But I noticed an other bug, what I would like to share.
The StartDisplay() function is earlier then where I define the adapter exactly so when I used the adapter.notifyDataSetChanged() then I got an exception as null object reference. So I put the function calling to the end of the initialization part and now everything is fine.
I am creating a notes app with java, i added room database to my app and when user saves a notes it adds it to database but doesn't shows in recyclerView immediately, when i reloads the app then it shows up, how and where should i insert notifyiteminserted so that recyclerView changes immediately
I have tried onResume Method but that results in app crash.
This is my MainActivity.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
#SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
This is my add_Activity.
package com.example.keepnotes;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import java.util.Objects;
public class addActivity extends AppCompatActivity {
MainActivity mainActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
Toolbar toolbar_add = findViewById(R.id.toolbar_add_activity);
setSupportActionBar(toolbar_add);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
toolbar_add.setNavigationIcon(R.drawable.back_button);
toolbar_add.setNavigationOnClickListener(view -> onBackPressed());
EditText titleText = findViewById(R.id.add_activity_title);
EditText bodyText = findViewById(R.id.add_activity_text);
Button saveBtn = findViewById(R.id.button);
DatabaseHelper database = DatabaseHelper.getDatabase(this);
saveBtn.setOnClickListener(view -> {
String titleBody = titleText.getText().toString();
String textBody = bodyText.getText().toString();
if (titleBody.equals("") && textBody.equals("")) {
Toast.makeText(addActivity.this, "Fields can't be empty",
Toast.LENGTH_LONG).show();
} else {
database.notesDao().addNotes(new Notes(titleBody, textBody));
finish();
}
});
}
}
How can i notify adapter the changes on each item add in database.
Here is my MainActivity after update to liveData.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
#SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
modelView = new ViewModelProvider(this).get(notesModelView.class);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
#Override
public void onChanged(List<Notes> notes) {
arrNotes = (ArrayList<Notes>) notes;
}
});
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
this is Dao.
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
#Dao
public interface NotesDao {
#Query("SELECT * FROM notesTable")
List<Notes> getAllNotes();
#Query("SELECT * FROM notesTable")
LiveData<List<Notes>> findAllNotes();
#Insert
void addNotes(Notes note);
#Update
void updateNotes(Notes note);
#Delete
void deleteNotes(Notes note);
}
And here is my ViewModel
package com.example.keepnotes;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class notesModelView extends AndroidViewModel {
DatabaseHelper databaseHelper;
public notesModelView(#NonNull Application application) {
super(application);
databaseHelper = DatabaseHelper.getDatabase(application.getApplicationContext());
}
public LiveData<List<Notes>> getAllNotes() {
return databaseHelper.notesDao().findAllNotes();
}
}
Here is my RecyclerView adapter
package com.example.keepnotes;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
Context context;
ArrayList<Notes> arrNotes;
DatabaseHelper databaseHelper;
RecyclerViewAdapter(Context context, ArrayList<Notes> arrNotes, DatabaseHelper databaseHelper) {
this.context = context;
this.arrNotes = arrNotes;
this.databaseHelper = databaseHelper;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.single_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") int position) {
holder.title.setText(arrNotes.get(position).title);
holder.body.setText(arrNotes.get(position).text);
holder.index.setText(String.valueOf(position + 1));
holder.llView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
AlertDialog.Builder alert = new AlertDialog.Builder(context)
.setTitle("Delete view")
.setMessage("Are you sure to delete")
.setIcon(R.drawable.ic_baseline_delete_24)
.setPositiveButton("yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
databaseHelper.notesDao().deleteNotes(new Notes(arrNotes.get(position).id,arrNotes.get(position).title,arrNotes.get(position).text));
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrNotes.size());
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alert.show();
return true;
}
});
}
#Override
public int getItemCount() {
return arrNotes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title, body, index;
CardView llView;
public ViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.text_title_view);
body = itemView.findViewById(R.id.text_text_view);
index = itemView.findViewById(R.id.index);
llView = itemView.findViewById(R.id.card_View);
databaseHelper = DatabaseHelper.getDatabase(context);
}
}
}
It deletes the selected notes but also crashes immediately after confirming delete.
and it throws following error
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{535e3b3 position=5 id=-1, oldPos=4, pLpos:4 scrap [attachedScrap] tmpDetached not recyclable(1) no parent} androidx.recyclerview.widget.RecyclerView{11f4816 VFED..... ......ID 31,171-689,1048 #7f090165 app:id/recycler_view}, adapter:com.example.keepnotes.RecyclerViewAdapter#fd652a0, layout:androidx.recyclerview.widget.StaggeredGridLayoutManager#32e1e59, context:com.example.keepnotes.MainActivity#286bccd
Remove this two line
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrNotes.size());
OLD ANSWER
First, if you use liveData you don't need to call the method
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
just keep a reference to the adapter instance and whenever there is a change from liveData call the notifyDataSetChanged method.
adapter = new RecyclerViewAdapter(this,new List<Notes>());
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(adapter);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
#Override
public void onChanged(List<Notes> notes) {
arrNotes.clear();
arrNotes.addAll(notes);
adapter.notifyDataSetChanged()
}
});
observe a LiveData object as it is not a LifecycleOwner
Use observeForever() on the LiveData, manually unregistering via removeObserver() when appropriate (onDestroy() of the service, if not sooner).
Bear in mind that standard service limitations apply here (e.g., services run for ~1 minute on Android 8.0+ unless they are foreground services), so it may be that you need to consider other approaches anyway. 🤞
Also you can read more in original post in here -> Link
I am new, and I am making an app that displays data in a cardView within a recyclerView in android studio. I am trying to be able to delete the data that is displayed on the cardView. The cardView and data gets deleted as it should, but once I go back to the activity holding the cardView and recyclerView, it's all still there. Does anyone know why this is happening? I'll post my code below
ReminderDBHelper:
package com.example.lasttry;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private Context context;
private ArrayList reminder_id, reminder_title, reminder_location, reminder_medication;
reminderDBHelper mydb;
Button reminderDelete;
CustomAdapter(Context context,
ArrayList reminder_id,
ArrayList reminder_title,
ArrayList reminder_location,
ArrayList reminder_medication) {
this.context = context;
this.reminder_id = reminder_id;
this.reminder_title = reminder_title;
this.reminder_location = reminder_location;
this.reminder_medication = reminder_medication;
}
#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, final int position) {
holder.reminder_id.setText(String.valueOf(reminder_id.get(position)));
holder.reminder_title.setText(String.valueOf(reminder_title.get(position)));
holder.reminder_location.setText(String.valueOf(reminder_location.get(position)));
holder.reminder_medication.setText(String.valueOf(reminder_medication.get(position)));
holder.reminderDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mydb = new reminderDBHelper(context);
String id = String.valueOf(reminder_id);
mydb.deleteData(id);
reminder_id.remove(holder.getAdapterPosition());
notifyItemRemoved(holder.getLayoutPosition());
}
});
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra("id", String.valueOf(reminder_id.get(holder.getAdapterPosition())));
intent.putExtra("title", String.valueOf(reminder_title.get(holder.getAdapterPosition())));
intent.putExtra("location", String.valueOf(reminder_location.get(holder.getAdapterPosition())));
intent.putExtra("medication", String.valueOf(reminder_medication.get(holder.getAdapterPosition())));
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return reminder_id.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView reminder_id, reminder_title, reminder_location, reminder_medication;
Button reminderDelete;
LinearLayout mainLayout;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
reminderDelete = itemView.findViewById(R.id.reminder_delete);
reminder_id = itemView.findViewById(R.id.reminder_id);
reminder_title = itemView.findViewById(R.id.reminder_title);
reminder_location = itemView.findViewById(R.id.reminder_location);
reminder_medication = itemView.findViewById(R.id.reminder_medication);
mainLayout = itemView.findViewById(R.id.mainLayout);
}
}
}
CustomAdapter:
package com.example.lasttry;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
private Context context;
private ArrayList reminder_id, reminder_title, reminder_location, reminder_medication;
reminderDBHelper mydb;
Button reminderDelete;
CustomAdapter(Context context,
ArrayList reminder_id,
ArrayList reminder_title,
ArrayList reminder_location,
ArrayList reminder_medication) {
this.context = context;
this.reminder_id = reminder_id;
this.reminder_title = reminder_title;
this.reminder_location = reminder_location;
this.reminder_medication = reminder_medication;
}
#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, final int position) {
holder.reminder_id.setText(String.valueOf(reminder_id.get(position)));
holder.reminder_title.setText(String.valueOf(reminder_title.get(position)));
holder.reminder_location.setText(String.valueOf(reminder_location.get(position)));
holder.reminder_medication.setText(String.valueOf(reminder_medication.get(position)));
holder.reminderDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mydb = new reminderDBHelper(context);
String id = String.valueOf(reminder_id);
mydb.deleteData(id);
reminder_id.remove(holder.getAdapterPosition());
notifyItemRemoved(holder.getLayoutPosition());
}
});
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, UpdateActivity.class);
intent.putExtra("id", String.valueOf(reminder_id.get(holder.getAdapterPosition())));
intent.putExtra("title", String.valueOf(reminder_title.get(holder.getAdapterPosition())));
intent.putExtra("location", String.valueOf(reminder_location.get(holder.getAdapterPosition())));
intent.putExtra("medication", String.valueOf(reminder_medication.get(holder.getAdapterPosition())));
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return reminder_id.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView reminder_id, reminder_title, reminder_location, reminder_medication;
Button reminderDelete;
LinearLayout mainLayout;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
reminderDelete = itemView.findViewById(R.id.reminder_delete);
reminder_id = itemView.findViewById(R.id.reminder_id);
reminder_title = itemView.findViewById(R.id.reminder_title);
reminder_location = itemView.findViewById(R.id.reminder_location);
reminder_medication = itemView.findViewById(R.id.reminder_medication);
mainLayout = itemView.findViewById(R.id.mainLayout);
}
}
}
I have searched stackOverflow and reddit, but nothing seems to work. I have tried making the array array list instead.
I am using recyclerview in fragment dynamically, now i want to open new activity on click of items with the same object / item.
AllCoursesFeagment.java
package com.example.learningapp.ui.NavigationDrawer.AllCourses;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.learningapp.Adapters.AllCoursesMyAdapter;
import com.example.learningapp.Interface.APIinterface;
import com.example.learningapp.Models.CourseListModel;
import com.example.learningapp.R;
import com.example.learningapp.Responses.CourseListResponse;
import com.example.learningapp.RetrofitAPIs.RetrofitAPI;
import com.example.learningapp.utility.ConstantData;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class AllCoursesFragment extends Fragment {
private RecyclerView recyclerView;
private List<CourseListModel> courseListModelList;
public AllCoursesFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static AllCoursesFragment newInstance() {
return new AllCoursesFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_all_courses,null);
recyclerView = view.findViewById(R.id.allCourseList_RV);
APIinterface apIinterface = RetrofitAPI.getClient().create(APIinterface.class);
Call<CourseListResponse> call = apIinterface.getAllCourses(ConstantData.AppKey);
call.enqueue(new Callback<CourseListResponse>() {
#Override
public void onResponse(Call<CourseListResponse> call, Response<CourseListResponse> response){
if (response.isSuccessful()){
courseListModelList = response.body().getCourseList();
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(new AllCoursesMyAdapter(getActivity(),courseListModelList));
}
}
#Override
public void onFailure(Call<CourseListResponse> call, Throwable t) {
Toast.makeText(getActivity(),"Something went wrong",Toast.LENGTH_LONG).show();
}
});
return view;
}
}
AllCoursesMyAdapter.java
This is my adapter class.
package com.example.learningapp.Adapters;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.learningapp.Activities.CheckoutActivity;
import com.example.learningapp.Models.CourseListModel;
import com.example.learningapp.R;
import java.util.List;
public class AllCoursesMyAdapter extends RecyclerView.Adapter<AllCoursesMyAdapter.RecyclerVH> {
Context context;
List<CourseListModel> courseListModelList;
public AllCoursesMyAdapter(Context context, List<CourseListModel> courseListModelList) {
this.context = context;
this.courseListModelList = courseListModelList;
}
#NonNull
#Override
public RecyclerVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.single_row_design_allcourses,parent,false);
return new RecyclerVH(view);
}
#Override
public void onBindViewHolder(#NonNull RecyclerVH holder, int position) {
final CourseListModel courseListModel = courseListModelList.get(position);
holder.courseTitle.setText(courseListModel.getCourseName());
holder.courseDesc.setText(courseListModel.getCourseDescription());
holder.buyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
moveToNewActivity();
//Toast.makeText(context,"Item Clicked"+position,Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, CheckoutActivity.class);
intent.putExtra("coursetitle",courseListModel.getCourseName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
private void moveToNewActivity () {
Activity activity = new Activity();
Intent i = new Intent(activity, CheckoutActivity.class);
context.startActivity(i);
((Activity) context).overridePendingTransition(0, 0);
}
#Override
public int getItemCount() {
return courseListModelList.size();
}
public class RecyclerVH extends RecyclerView.ViewHolder {
TextView courseTitle,courseDesc;
Button buyBtn;
public RecyclerVH(#NonNull View itemView) {
super(itemView);
courseTitle = itemView.findViewById(R.id.course_title);
courseDesc = itemView.findViewById(R.id.course_desc);
buyBtn = itemView.findViewById(R.id.btn_buycourse);
}
}
}
I'm gettng crashed when i clicked item
holder.buyBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
moveToNewActivity();
//Toast.makeText(context,"Item Clicked"+position,Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context, CheckoutActivity.class);
intent.putExtra("coursetitle",courseListModel.getCourseName());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
Here i am using a stored list of objects and now i want to move to the new activity when i clicked on an item with given position, but i am not able to do that.
private void moveToNewActivity () {
Activity activity = new Activity(); //this is wrong, delete this
...
}
you can't and shouldn't create an instance of an activity like this, it's something the OS has to schedule and handle for you.
you already seem to have context defined somewhere, so that means:
private void moveToNewActivity () {
Intent i = new Intent(context, CheckoutActivity.class);
context.startActivity(i);
...
}
so that means:
#Override
public void onClick(View v) {
moveToNewActivity();
}
can anyone explain to me how can I create a new recycle and add items to that recycle view staring from another recycle view inside another activity?
Basically I want to create a shopping cart, for now, I retrieved the data from Firebase dataset and displayed it inside a recycle view but now I would like to send this data to the shopping cart(the shopping cart is inside another activity), I'm able to send the data but I can't understand how to display the data inside the new recycle view of this new activity. I need this because I want to see the items that I added to the shopping list so then I can pay.
Below I will attach a photo to explain myself better.
My problem is that I can't understand how to add the sent data to a recycle view again in the new activity.
I'm new to android so it's the first time I'm doing this thing.
Thank you in advance for your help.
My code:
SearchItemsActivity :
package com.example.ipill;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.Intent;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import java.util.ArrayList;
import java.util.List;
public class FirebaseSearch extends AppCompatActivity {
private EditText mSearchField;
private ImageButton mSearchBtn;
private ImageButton AddToCart;
private ImageButton Cart;
String searchText="";
private RecyclerView mResultList;
private DatabaseReference mUserDatabase;
private static ArrayList<Users> arrayList = new ArrayList<>();
public static int cart_count = 0;
RecyclerView productRecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_firebasesearch);
mUserDatabase = FirebaseDatabase.getInstance().getReference("Users");
mSearchField = findViewById(R.id.search_field);
mSearchBtn = findViewById(R.id.search_btn);
mResultList = findViewById(R.id.result_list_cart);
AddToCart = findViewById(R.id.imageButton2);
Cart = findViewById(R.id.cartButton);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
mSearchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchText = mSearchField.getText().toString();
firebaseUserSearch(searchText);
}
});
Cart.setOnClickListener(new View.OnClickListener() {
private Object Tag="Activity";
#Override
public void onClick(View v) {
if (cart_count < 1) {
} else {
startActivity(new Intent(FirebaseSearch.this, CartActivity.class));
}
}
});
}
private void firebaseUserSearch(String searchText) {
Toast.makeText(FirebaseSearch.this, "Started Search", Toast.LENGTH_LONG).show();
Query firebaseSearchQuery =
mUserDatabase.orderByChild("Name").startAt(searchText).endAt(searchText + "\uf8ff");
FirebaseRecyclerAdapter<Users, UsersViewHolder> firebaseRecyclerAdapter = new
FirebaseRecyclerAdapter<Users, UsersViewHolder>(
Users.class,
R.layout.list_layout,
UsersViewHolder.class,
firebaseSearchQuery
) {
#Override
protected void populateViewHolder(UsersViewHolder viewHolder, Users model, int position) {
viewHolder.getDetails(model.getName(), model.getSurname(),model.getPrice());
viewHolder.setDetails(model.getName(), model.getSurname(),model.getPrice());
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
#Override
protected void onStart() {
super.onStart();
invalidateOptionsMenu();
}
// View Holder Class
public static class UsersViewHolder extends RecyclerView.ViewHolder {
View mView;
String nome;
String surname;
Long prezzo;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
ImageButton addToCart = (ImageButton)mView.findViewById(R.id.imageButton2);
addToCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cart_count++;
Context context = v.getContext();
Intent intent = new Intent(context, CartActivity.class);
intent.putExtra("Name",nome);
intent.putExtra("Surname",surname);
intent.putExtra("Prezzo",Long.toString(prezzo));
context.startActivity(intent);
}
});
}
public void getDetails(String name,String cognome,Long price){
nome=name;
surname=cognome;
prezzo=price;
}
public void setDetails(String name, String surname, Long price) {
TextView user_name = (TextView) mView.findViewById(R.id.name_text);
TextView user_surname = (TextView)mView.findViewById(R.id.status_text);
TextView user_price = (TextView)mView.findViewById(R.id.price);
user_name.setText(name);
user_surname.setText(surname);
user_price.setText(Long.toString(price));
}
}
}
enter code here
The second activity where I receive the data and where I want to create the recycle view
package com.example.ipill;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collection;
public class CartActivity extends AppCompatActivity {
public static TextView grandTotal;
public static int grandTotalplus;
// create a temp list and add cartitem list
public static ArrayList<Users> temparraylist;
RecyclerView cartRecyclerView;
Button proceedToBook;
Context context;
String name,surname,price;
private static ArrayList<Users> arrayList2 = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
context = this;
temparraylist = new ArrayList<>();
proceedToBook = findViewById(R.id.buyNow);
grandTotal = findViewById(R.id.TotalPrice);
cartRecyclerView=findViewById(R.id.cartList);
String passedArg = getIntent().getExtras().getString("Name");
name=passedArg;
String passedArg2 = getIntent().getExtras().getString("Surname");
surname=passedArg2;
String passedArg3 = getIntent().getExtras().getString("Price");
price=passedArg3;
System.out.println("DATA"+name+surname+price);
cartRecyclerView.setHasFixedSize(true);
cartRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
you can re use the cart adapter just implement a recylerView into new Activity and make the cart adater object and set it into the new reyclerView and it done