How to programmatically change one RecyclerView item style? - android

I've got this RecyclerView, it's showing a list of persons with their names, phones and birthday.
I want to change the color of the item if the person's birthday is today, but I want to know if I should do the verification and change on my RecyclerView's adapter inside the OnBindViewHolder method, or if I should do it inside my activity calling my LinearLayoutManager or calling the item using the RecyclerView.getChildAt() method.
Should I go whit the first option, using the onBindViewHolder?

YES . Should you choose to make changes in the onBindViewHolder().
We'll take a sample:
#Override
public void onBindViewHolder(FeedsViewHolder feedViewHolder, int i)
{
if(d1.feeds.get(i).getFeedContentType().equals("b-day")) // <-- Pointing to the List that contains value, and checks if it equals to a sample string
{
feedViewHolder.n1.setText("Birthday"); // <-- if it equals, party time :D , and sets text to the corresponding TextView in the RecyclerView
}
}
Hope it helps :)

Related

Get updated data from network with pagination in android

I'm using pagination to get data from network as the only datasource. In the PagedListAdapter I have a button which on click will update the data in the network now I need to get the updated data and change the view for that item. How do I do that?. Is there a way to achieve this without using db?...
lets say I have a Model named Post and it has a field named isSaved. so what I'm doing rt now is when I click the save button in the PagedListAdapter view then I'm calling an api to update that field ..so now I want to get the updated value for that particular post item and change the button's text as saved....since i'm using adapter.submit(listOfPost), the list is the same so DiffUtil itemCallback isn't being called...What should I do??
Suppose when you pass page 1 then take example its returning you 30 items. So all you have to check here is whether recyclerview can scroll vertically or not. If not then increase the page number and call api method again.
And to check whether recyclerView have more item to scroll below method will help you.
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
if(!mRecyclerView.canScrollVertically(1)){
// search the next page
searchNextPage();
}
}
});
For more details this link will be helpful for you: https://github.com/mitchtabian/RestApiMVVM

Unable to get the position in a RecyclerView

I am trying to create a dynamic survey app, using a RecyclerView. I have no problem on initializing the primary questions. The issue is when I try to insert a row in the recyclerView.It is not placed where it is expected to be. I wanted the row to be inserted next to the current row. I tried several methods like getAdapterPosition, getLayoutPosition for viewholder but I cant get the selected correct position of the view. Furthermore, the RecyclerView does stores the old location of a view when something is inserted. Could someone help me to figure this out or is there any easier approach. Furthermore, Thank you guys, I'm a newbie programmer.. Here is a snippet of my Adapter where I create and initialize dynamic views.
What i always do and works fine is to use tag.
for example you have a radio button and you have an item ( Question , single choice etc... ) .
before you assign a clicklistener to your view just put that item as tag
MYVIEW.setTag(MyItem);
so in your clicklistener just do this :
new View.OnClickListener() {
#Override
public void onClick(View v) {
ITEM item = (ITEM)v.getTag();
int alwaysTruePosition = items.indexOf(item);
...
}
}
Important note is that you should define equal method in your ITEM class and there should be a unique identifier which helps you to define are two objects the same or not. (for example a unique id or unique name )

RecyclerView notifyItemRemoved(position) not working properly

I have a RecyclerView with its RecyclerView.Adapter and view holder. I am trying to delete an item from list, code as follows inside onClick() on delete button in the ViewHolder
int position = getAdapterPosition();
if(position > -1)
{
Place place = placeList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, getItemCount());
}
Despite removing the view and doing the animation (list also gets affected), the old view (or lower one) still exist or drawn again.
For example, if the list starts with size = 5, then i try to remove index 4, he remove 4, then still draw 5 views.
EDIT
If i remove notifyItemRangeChanged() then it does that bug only if i do the following
1- click on delete
2- click button very quickly that takes me to new view
3- going back to the list where i can delete
4- start deleting, and bug happens. 1 item still remain even though the List size = 0 (getItemCount is called with 0).
If i only call NotifyDataSetChanged(), then it removes item, but view just stays there !!
Any help or suggestion is appreciated.
Thanks.
EDIT complete class LINK
Try this:
placeList.remove(position);
notifyItemRemoved(position);
use below code it will solve your problem.
holder.deleteImg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(list.size()!=0){
list.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,list.size());
}
}
});
I've had the same problem, notifyItemRangeChanged() call didn't help while notifyDataSetChanged() did (though stopped the animation). But I am using the ItemTouchHelper on the RecyclerView (to allow for moving items around), and it became obvious that this class was causing the trouble.
The only difference in my case is that to reproduce this overlap-after-delete bug, user has to long press on an item while deleting it.
After I modified the overriden isLongPressDragEnabled() method of ItemTouchHelper.Callback to return false instead of true, the issue was solved.
lastImages.remove(position); (lastImages equals your array list)
newContentAdapter.notifyDataSetChanged();
it is works. You have to remove it in your array not item. then notify adapter. Thats all
for me notifyItemRemoved and notifyDataSetChanged doesnt work. I tried everything , only solution that worked for me is calling or reloading recycler view inside onSwiped method!
you don't have to create new reference of place list.that need to declared as array list. you can't add or remove a object from list. you can do that only with arraylist.
change this lines
private List<Place> placeList;
Place place = placeList.remove(position);
to
private ArrayList<Place> placeList;
// other codes
placeList.remove(position);
// print placeList to confirm
notifyItemRemoved(position);
I had this issue
when I'm using notifyDataSetChanged() it works fine but I wanted the animation so I used notifyItemRemoved(position) for animation then I used notifyDataSetChanged() but I delayed the interval between those functions
I made extension for it you can use it on any RecylcerView
fun RecyclerView.removeItem(position: Int){
adapter?.notifyItemRemoved(position)
handler.postDelayed({
adapter?.notifyDataSetChanged()
},300)
}
You need to update you adapter;
Create method in Adapter class where you will be put your data.
For example : setData(List<Place> data);
When last item in list you need to write: adapter.setData(null);
I had the same problem. Just set list = null. It's all.

How to change number of column of a gridview at same visible item. Android

I am writing an android app where I am using a grid view to display some items. I want to give users a configurable view where they can change the no of columns on the activity by clicking floating action button. I am changing the column no using
gridView.setNumColumns(selectedColumnNo);
This is working fine But the problem is if a user changes no of column after some scrolling the First Visible Position is set to the first item of the array list, so the user has to scroll the view again. Can someone please tell me where I am doing wrong. Or Is this the proper way to do this or should I use a different approach.
A code snippets will be helpful
Thanks.
Update::
currently I am using the bellow snippets
findViewById(R.id.fab).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int firstPosition = gv.getFirstVisiblePosition();
if(gv.getNumColumns()==2)
{
gv.setNumColumns(1);
gv.setSelection(firstPosition);
}
else {
gv.setNumColumns(2);
gv.setSelection(firstPosition);
}
}
});
Now the problem is on every 4th switch grid view is showing the first element of the arraylist
Right before you call setNumColumns(), save the GridView's first visible position:
int firstPosition = gridView.getFirstVisiblePosition();
Then, after you change the number of columns, pass that integer to setSelection():
gridView.setSelection(firstPosition);
"Selection", counter-intuitively, is not the same thing as "activation". It will ensure that the view is on-screen, but not visibly affect it in any other way.

how to access ListView with CheckedTextView?

I'm now developing an application that uses a ListView with a
CheckedTextView on every item that managed by an ArrayAdapter to
support multiple chooses. The contents in my ListView are dynamic, that
means, can be changed during runtime. Now I try to use
ListView.getCheckedItemPositions() to get all checked items, Because I want
to save all the checked positions and auto-check them when user go back to
this page again. So I need to save checked results for every page.
For the first page everything works fine as expected. But when user goes to
another page and make some chooses, the result array that ListView returned
contains some positions that are never checked. I don't why ListView has
this strange behavior. Even for a page that in fact no checked happens but
ListView gives me a result that indicates there's one item has been checked.
could anyone who can teach me how to get the position of CheckedTextView
in its OnClickListener callback?
example code is appreciate.
Thanks in advance...
The listview recycles its views so when you go to a different page and then return to the previous page, the listview recalls the getView() function for its views. To make sure that the order of the checked views are not mixed up, create an arraylist that contains the check state of all the views before initializing the adapter. Then pass the arraylist as an argument for the adapter's constructor. There, in the getView() function, set the checked state of each checkable textview based on the arraylist. Then, return to the activity class and override the onItemClick() event. Using the view that is given to you when the function is called, do the following to get the checkable textview and set its checked state:
listView1.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View selectedView, int position , long id)
{
CheckedTextView tv = (CheckedTextView)selectedView.findViewById(R.id.textview);
if (tv.isChecked())
{
tv.setChecked(false);
checkStatesOfViews.get(position) = false;
}
else
{
tv.setChecked(true);
checkStatesOfViews.get(position) = true;
}
}
});

Categories

Resources