How to update recyclerview the simplest way using notifyDataSetChanged - android

I'm trying to update my recyclerview using notifyDataSetChanged() but it doesn't work. I am setting the adapter to the recyclerview like this:
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(ctx, LinearLayoutManager.VERTICAL, false);
lstSong.setLayoutManager(mLayoutManager);
lstSong.setItemAnimator(new DefaultItemAnimator());
lstSong.addItemDecoration(new GridSpacingItemDecoration(2, dpToPx(0), true));
arrSong = new ArrayList<Song>();
arrSong = kFunc.getAllSong();
songAdapter = new SongAdapter(ctx, arrSong);
lstSong.setAdapter(songAdapter);
This lines of code displays the data. But when i add a new data and refresh the recyclerview with songAdapter.notifyDataSetChanged(); the data won't show up. I know i can display it by using setAdapter() but i want to do it properly.
I add the data before I make the refresh. This is the code:
kFunc = new Function(ctx);
Song song = new Song();
song.setTitle(title);
song.setArtist(artist);
song.setYear_released(yearReleased);
song.setAlbum(album);
song.setGenre(genre);
song.setDuration(duration);
song.setCode(code);
song.setLyrics(lyrics);
kFunc.addSong(song);
dialog.dismiss();
arrSong = kFunc.getAllSong();
songAdapter.notifyDataSetChanged();

Create a method inside adapter like
public updateItems(ArrayList<Song> songs){
arrSong=songs;
}
And while getting new values in your class call the method using adapdter object
lstSong.updateItems(arrSong);
notifyDataSetChanged();

I don't know where you added new item to RecyclerView.Adapter. This is a sample code to add and set a item. More detail Sample RecyclerViewAdapter
#Override
public void addItem(M item) {
items.add(item);
notifyItemInserted(items.size() - 1);
}
#Override
public void addItem(int position, M item) {
items.add(position, item);
notifyItemInserted(position);
}
#Override
public void addAllItems(List<M> items) {
this.items.addAll(items);
notifyDataSetChanged();
}
#Override
public void setItems(List<M> items) {
this.items = items;
notifyDataSetChanged();
}

You should try by updating the list of the songs before you notify the adapter.
for example
arraySongs = <retrive updated data of the song>;
adapter.notifyDataStateChanged()
if you are in ListView which you are not but for you information only.
adapter.lstSong =<updated songs List>;
adapter.notifyDataStteChanged();
try this this worked for me.
happy coding. :)

Related

RecyclerView duplicates every item

I have a problem dealing with recyclerview, when i return back to the activity after opening another activity, it duplicates all the items i displayed. Is there any way to fix this?
Like on list view, it just automatically clears the list and then display it again. can you show me how? thanks
OnCreate
int x = 0;
for(String Name : property_name){
JSONObject jsonObject = arrayResponse.getJSONObject(x);
property_id[x] = jsonObject.getString("property_id");
property_name[x] = jsonObject.getString("property_name");
type[x] = jsonObject.getString("property_type");
price[x] = jsonObject.getString("price");
address[x] = jsonObject.getString("address");
ListingNearby listingNearby = new ListingNearby(property_id[x], property_name[x], type[x], price[x], Math.round(distance[x]));
x++;
list.add(listingNearby);
}
recyclerView = (RecyclerView) findViewById(R.id.ln_recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
adapter = new ListingNearbyAdapter(list);
recyclerView.setAdapter(adapter);
I wonder what to put in onResume so that the listview clears the list and then display it again.
Just try to list.clear() before you begin your loop. I guess your list is kind of static variable.
override these two method in your adapter:
#Override
public int getItemCount() {
return reviewModels.size();
}
#Override
public long getItemId(int position) {
return position;
}
it worked for me

Empty Recycler view is not getting updated with new data

I intialize my recycler view adapter with an empty arraylist initially.
Then later once I fetch data from API I try to update the adapter by calling notifyDataSetChanged() but none of call back methods in my adapter is getting fired
void initRecyclerView()
{
myList = new ArrayList<>();
myRecyclerAdapter = new myRecyclerAdapter(getActivity(), myList, "");
myRecyclerView.setAdapter(myRecyclerAdapter);
linearLayoutManager = new LinearLayoutManager(getActivity());
myRecyclerView.setHasFixedSize(true);
myRecyclerView.setLayoutManager(linearLayoutManager);
}
After getting data from API I just update the adapter as follow :
void updateRecyclerView(ArrayList<Data> newList)
{
if (myList.isEmpty())
linearLayoutManager.removeAllViews();
myList.clear();
myList.addAll(newList);
myRecyclerAdapter.notifyDataSetChanged();
}
void updateRecyclerView(ArrayList<Data> newList)
{
//you don't have to removeviews
// if (myList.isEmpty())
// linearLayoutManager.removeAllViews();
myList.clear();
myList.addAll(newList);
myRecyclerAdapter.notifyDataSetChanged();
}
I made a costliest mistake and ponder around something else instead of looking it at different aspect.
I had SwipeRefreshLayout that wraps RecyclerView.
I should've just use setRefreshing(false) once data downloaded through API call. Instead I used setVisibility(VIEW.GONE) on mymSwipeRefreshLayout`.
This visibility change of SwipeRefreshLayout impacted RecyclerView within.
I hope none will do this mistake. Perhaps someone might come across this tiniest mistake so I Mark my answer as accepted answer.
First of all try to set layout manager and then set adapter to list :
void initRecyclerView()
{
linearLayoutManager = new LinearLayoutManager(getActivity());
myRecyclerView.setHasFixedSize(true);
myRecyclerView.setLayoutManager(linearLayoutManager);
myList = new ArrayList<>();
myRecyclerAdapter = new myRecyclerAdapter(getActivity(), myList, "");
myRecyclerView.setAdapter(myRecyclerAdapter);
}
Also pay attention that if you want to change data set or notify your adapter about the changes, you should do it in your main thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
myList.clear();
myList.addAll(newList);
myRecyclerAdapter.notifyDataSetChanged();
}
});

recyclerView ClickListener return null after notifyDataSetChanged()

i am using a recyclerView and loading the data from database.The recyclerView item have 2 buttons. The recyclerView loads fine and clicks work fine for the following code.
allData=db.getCatData(CATEGORYLIST_CIDD,1);
textlistadapter = new TextListAdapter(getActivity(), allData);
recyclerView.setAdapter(textlistadapter);
later i rearrange the adapter data for displaying the data in descending order by using this code
db=new DatabaseHandler(getActivity().getApplicationContext());
allData=db.getCatData(CATEGORYLIST_CIDD,order_id);
textlistadapter = new TextListAdapter(getActivity(), allData);
recyclerView.setAdapter(textlistadapter);
textlistadapter.notifyDataSetChanged();
Now the items are rearranged on the recyclerView, but the onShareButtonClickListener returns null, here is the code of the adapter.
private OnShareButtonClickListener onShareButtonClickListener;
public interface OnShareButtonClickListener {
void onItemClick(View view, Pojo obj, int position);
}
public void setOnShareButtonClickListener(final OnShareButtonClickListener onShareButtonClickListener) {
this.onShareButtonClickListener = onShareButtonClickListener;
}
the click listener code is here
holder.bt_share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Snackbar.make(view, "Share Clicked", Snackbar.LENGTH_SHORT).show();
if (onShareButtonClickListener != null) {
onShareButtonClickListener.onItemClick(view, c, position);
}
}
});
The click does not work since the onShareButtonClickListener is null.
The same code works well for the first time and once i change the order then the click events are not working, all other functions are working well.
you should only need to do this once:
textlistadapter = new TextListAdapter(getActivity(), allData);
recyclerView.setAdapter(textlistadapter);
later on, if you want to update/change the data, then you should do something like this:
textlistadapter.setListItems(allData);
textlistadapter.notifyDataSetChanged();
Where setListItems() is a public method in your adapter, an example like this:
public void setListItems(List<> allData) {
this.data.clear();
this.data.addAll(allData);
}
It's easy to understand what you are doing wrong. You populate an array which will feed your adapter with data, that meaning that, after setting the adapter, if you want it's data to change, you only need to change the array you populated the data with, and notify the adapter for the data change.
For example:
myData = db.getData();
myAdapter = new MyAdapter(this,myData);
recyvlerview.setAdapter(myAdapter);
Now every time you want to change the data, you only need to change your myData and notifity the adapter
myAdapter.notifyDataSetChange();
Basically instead of doing this:
db=new DatabaseHandler(getActivity().getApplicationContext());
allData=db.getCatData(CATEGORYLIST_CIDD,order_id);
textlistadapter = new TextListAdapter(getActivity(), allData);
recyclerView.setAdapter(textlistadapter);
textlistadapter.notifyDataSetChanged();
This should suffice
db=new DatabaseHandler(getActivity().getApplicationContext());
allData=db.getCatData(CATEGORYLIST_CIDD,order_id);
textlistadapter.notifyDataSetChanged();

How to edit RecyclerView data

I have a RecyclerView which displays two pieces of data in each row.
Both are from a List Players.
What I need is to update the second piece of data (which is a counter, an int) each time an element is clicked.
Basically I have this players List modified, but don't know how to put it back in to the RecyclerView edited.
My Adapter Code
TextView name;
TextView counter;
CoursesViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
name = (TextView) itemView.findViewById(R.id.textName);
counter = (TextView) itemView.findViewById(R.id.textCounter);
}
[...]
#Override
public void onBindViewHolder(CoursesViewHolder holder, int position) {
Player player = mArrayCourses.get(position);
holder.name.setText(player.getName());
holder.counter.setText(String.valueOf(player.getCount()));
}
What I've tried
adapter = new CoursesAdapter(players);
myList.setAdapter(adapter);
myList.invalidate();
Edit:
// Piece of code of the activity where my RecyclerView is
myList = (RecyclerView) findViewById(R.id.playersVote);
myList.setLayoutManager(new LinearLayoutManager(this));
adapter = new CoursesAdapter(players);
myList.setAdapter(adapter);
// RecyclerView with a click listener
CoursesAdapter clickAdapter = new CoursesAdapter(players);
clickAdapter.setOnEntryClickListener(new CoursesAdapter.OnEntryClickListener() {
#Override
public void onEntryClick(View view, int position) {
// Let each player vote (ghosts too)
Player player = players.get(position);
player.incrementCount();
//Toast.makeText(ListPlayersVote.this, String.valueOf(player.getCount()), Toast.LENGTH_SHORT).show();
votes++;
Every time that your data change you should notify those changes in the adapter, using notifyDataSetChanged()
notifyDataSetChanged(): Notifies the attached observers that the underlying data has been
changed and any View reflecting the data set should refresh itself.
like this:
adapter = new CoursesAdapter(players);
myList.setAdapter(adapter);
....
....
adapter.notifyDataSetChanged();
Use the below code to change the particular Item in a recyclerview
public void updatedelivact(String value,int index) {
ChatMessage chatMessage = getItem(index);
Collection<Integer> readIds = chatMessage.getDeliveredIds();
readIds.add(userid);
chatMessage.setReadIds(readIds);
//To change the perticular item
notifyItemChanged(index);
}

Remove all items from RecyclerView

I am trying to remove all the elements from my RecyclerView in my onRestart method so the items don't get loaded twice:
#Override
protected void onRestart() {
super.onRestart();
// first clear the recycler view so items are not populated twice
for (int i = 0; i < recyclerAdapter.getSize(); i++) {
recyclerAdapter.delete(i);
}
// then reload the data
PostCall doPostCall = new PostCall(); // my AsyncTask...
doPostCall.execute();
}
But for some reason the delete method I created in the adapter is not functioning properly:
in RecyclerAdapter.java:
public void delete(int position){
myList.remove(position);
notifyItemRemoved(position);
}
public int getSize(){
return myList.size();
}
I think every other item in my list gets deleted instead of the entire list.
With a listview it was so easy and I simply called adapter.clear().
Can someone please help me fix up the code?
I think I should be using notifyItemRangeRemoved(...,...); but I am not sure how. TIA
This works great for me:
public void clear() {
int size = data.size();
if (size > 0) {
for (int i = 0; i < size; i++) {
data.remove(0);
}
notifyItemRangeRemoved(0, size);
}
}
Source: https://github.com/mikepenz/LollipopShowcase/blob/master/app/src/main/java/com/mikepenz/lollipopshowcase/adapter/ApplicationAdapter.java
or:
public void clear() {
int size = data.size();
data.clear();
notifyItemRangeRemoved(0, size);
}
For you:
#Override
protected void onRestart() {
super.onRestart();
// first clear the recycler view so items are not populated twice
recyclerAdapter.clear();
// then reload the data
PostCall doPostCall = new PostCall(); // my AsyncTask...
doPostCall.execute();
}
Avoid deleting your items in a for loop and calling notifyDataSetChanged in every iteration. Instead just call the clear method in your list myList.clear(); and then notify your adapter
public void clearData() {
myList.clear(); // clear list
mAdapter.notifyDataSetChanged(); // let your adapter know about the changes and reload view.
}
setAdapter(null);
Useful if RecycleView have different views type
recyclerView.removeAllViewsInLayout();
The above line would help you remove all views from the layout.
For you:
#Override
protected void onRestart() {
super.onRestart();
recyclerView.removeAllViewsInLayout(); //removes all the views
//then reload the data
PostCall doPostCall = new PostCall(); //my AsyncTask...
doPostCall.execute();
}
This is how I cleared my recyclerview and added new items to it with animation:
mList.clear();
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
//reset adapter with empty array list (it did the trick animation)
mAdapter = new MyAdapter(context, mList);
recyclerView.setAdapter(mAdapter);
mList.addAll(newList);
mAdapter.notifyDataSetChanged();
Help yourself:
public void clearAdapter() {
arrayNull.clear();
notifyDataSetChanged();
}
I use this. This actually clears the recylerview completely. I had tried adapter.notifyDataSetChanged(); but it was just not updating any view in my case. Of course U had cleared the list first. But below code works fine and clears view of recyclerview completely.
listName.clear(); // clear list
adapter = new ModelAdaptor(Activity.this, listName);
recyclerView.setAdapter(adapter);
Another way to clear the recycleview items is to instanciate a new empty adapter.
mRecyclerView.setAdapter(new MyAdapter(this, new ArrayList<MyDataSet>()));
It's probably not the most optimized solution but it's working like a charm.
ListView uses clear().
But, if you're just doing it for RecyclerView. First you have to clear your RecyclerView.Adapter with notifyItemRangeRemoved(0,size)
Then, only you recyclerView.removeAllViewsInLayout().
For my case adding an empty list did the job.
List<Object> data = new ArrayList<>();
adapter.setData(data);
adapter.notifyDataSetChanged();
private void clearRecyclerView() {
CustomListViewValuesArr.clear();
customRecyclerViewAdapter.notifyDataSetChanged();
}
use this func
On Xamarin.Android, It works for me and need change layout
var layout = recyclerView.GetLayoutManager() as GridLayoutManager;
layout.SpanCount = GetItemPerRow(Context);
recyclerView.SetAdapter(null);
recyclerView.SetAdapter(adapter); //reset
You have better clear the array-list that you used for recyleview adapter.
arraylist.clear();
public void clearData() {
mylist.removeAll(mylist);
mAdapter.notifyDataSetChanged();
recyclerView.setAdapter(mAdapter);
}

Categories

Resources