I have a horizontal Recyclerview which displays bitmaps.
The Way it is implemented is I have a Imageview and a recyclerview underneath it. The currently selected item is displayed on the image view. The selected image view is given a blue background to indicate it is selected. I can choose images from the gallery and each time a new image is selected, I want to scroll to the last position and make the item selected.
The list of images is maintained in a array list and each time a new image is added, I add the image to the list and notifyDataChanged().
Currently when I am binding a view, I toggle the visibility of the blue background in
public void onBindViewHolder(final MyRecyclerViewHolder holder, int position) {
}
But the problem is, if the child is off screen, the bind view is not called and I dont scroll to the new position.
I read through the documentation of recycler view and could not figure out how to scroll to that particular child view. I do not there is a SmoothScrollTo method but my question is where do I trigger this ?
There is one solution:
In your RecyclerView adapter, add a variable selectedItem and a methods setSelectedItem():
private static int selectedItem = -1;
... ...
public void setSelectedItem(int position)
{
selectedItem = position;
}
In your onBindViewHolder(...), add:
#Override
public void onBindViewHolder(ViewHolder holder, final int position)
{
... ...
if(selectedItem == position)
holder.itemView.setSelected(true);
}
Now you can scroll to specific item and set it selected programmatically by:
myRecyclerViewAdapter.setSelectedItem(position_scrollTo);
myRecyclerView.scrollToPosition(position_scrollTo);
For example, you want to scroll to last position and make it selected, just:
int last_pos = myRecyclerViewAdapter.getItemCount() - 1;
myRecyclerViewAdapter.setSelectedItem(last_pos);
myRecyclerView.scrollToPosition(last_pos);
[UPDATE]
To add item and make it selected, you should have a addItem(...) method in adapter, which will add item to item list. After adding item, refresh list and scroll to new added/latest item:
myRecyclerViewAdapter.addItem(...);
myRecyclerViewAdapter.notifyDataSetChanged();
myRecyclerViewAdapter.setSelectedItem(myRecyclerViewAdapter.getItemCount() - 1);
myRecyclerView.scrollToPosition(myRecyclerViewAdapter.getItemCount() - 1);
Hope this help!
Your view will not be created until you scroll to the item.
You must call
recyclerView.scrollToPosition(position)
Where position is
recyclerView.getAdapter().size()
So the item became visible.
Use RecyclerView LayoutManager to scroll item at position
recyclerView.getLayoutManager().scrollToPosition(position)
I forgot to address the timing part ideally this should be called when the adapter has been identified of the dataset change.
You could use
recyclerView.smoothScrollToPosition(View.FOCUS_DOWN);
Related
I have a RecyclerView. Every layout contains expandle view within itself.
With item click expandle view of clicked item is expands. And if I'll click on two items there is will be two items with expanded view in my RecyclerView. I need to close others item's expandles view with item click. Only one item with expanded expandle view must be in recycler.
How do I can make this?
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
holder.exp.collapse();
holder.itemView.setOnClickListener(v -> {
holder.exp.expand();
});
Save the Position of previously expanded position make a property in lists object like some boolean isOpen or something set it to false or true as required now on Click of a new row
list.get(prevPosition).setIsOpen(false);
then
notifyItemChanged(prevPosition);
make sure you have handled in your bindViewHolder something like this
if(list.get(postition).getIsOpen()==false){
//hide your expanded list
}
I am making a list with RecyclerView, let's call it VariationList.
VariationList will contains items (VariationsItem).
VariationsItems will contain a title, and a RecyclerView (VariationsItemsList).
If I click on an item of VariationsItemsList, I want the following VariationsItem to refresh, and eventually add or delete some of their items.
Is there any solution to refresh a specific item from the Adapter ?
Or do I need to delete all items, then add them after modification ?
I know it is pretty confusing, so here is an example of my model :
In red, this is the list of green items.
Each green item contains a title, and a blue list.
For example, if I click on "Petit", I want to refresh the "Test" list.
If I click on "Vert", I want to refresh the "Taille" list and the "Test" list, to eventually add some items, or delete some.
you can do it in onBindView holder in recycle view adapter
`` #Override
public void onBindViewHolder(Viewholder holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//code what ever you want to change use position
}
});
});
or you can use https://github.com/greenrobot/EventBus for change any item from outside of activity
I have a RecyclerView, it will show close icon in the last item view,
but when I add new data in the Adapter,
the old item does not refresh their view, it just adds new item view in the RecyclerView.
How could I update the old last item view?
I tried to use notifyItemChanged(int) but it didn't work.
for(int i = lastPosition(); i < mAdapter.getItemCount() - 1; i++) {
mAdapter.notifyItemChanged(i);
}
Add below code after adding item in listview...
mAdapter.notifyDataSetChanged();
you can call this whenever you want to update the item of recyclerview list
mAdapter.notifyItemChanged(ITEM_INDEX);
//ITEM_INDEX IS THE POSITION
Thanks for your help, I have find the problem
the problem is not in adapter, it in my viewholder
my xml layout show the icon in default,
when it is the last item ,I set the icon Gone
public static void hideBottomLine(BaseViewHolder h) {
h.line.setVisibility(View.GONE);
}
when i notifyItemChanged it ,I thought it will show default, but not! So when I add method
public static void showLine(BaseViewHolder h) {
h.line.setVisibility(View.VISIBLE);
}
now it work...
I have got a RecyclerView item looking like this
I want to achieve that when I click on item the ImageView will get overlay over it and TextView will become bold. I know how to use adapter and where to handle item clicks. I also know how to make overlay or bold text. I only want to know how to make this item selectable to get the behavior I described above. Because I found only tutorials to change background of item when clicked.
Based on this
I only want to know how to make this item selectable to get the behavior I described above.
So basically you need a way to tell the ViewHolder that the current item is selected, such that in onBindViewHolder() the items are rendered as per need.
I can think of this: Make a model of the item youre adding to the RecyclerView. Add a key as boolean isSelected = false in it.
And inside your onBindViewHolder where youre implementing the onClick()interface. do this:
... new OnClickListener({
... onClick(){
// take the item and set the isSelected flag
list.get(position).setIsSelected(true):
notifyDataSetChanged();
// alternatively you can also toggle this flag.
}
});
and while loading inside onBindViewHolder to this:
if (list.get(position).isSelected()) {
// highlight aka set overlay and bold text to view
} else {
// as per recyclerview doc, reset the views.
}
All you need is having a variable to hold the selected index. Then decorating the selected item in onBindViewHolder() method.
int selectedIndex = 0;
...
public void onBindViewHolder(ViewHolder viewHolder, int position) {
if (selectedIndex == position) {
// Do things you want
}
}
There is a way to horizontally center the last item in a recycler view.
So...if there is only one item this item will be centered and will not scroll, if there is two or more that can fill the width it will be possible to scroll, but the last item will appears first on center
For example. In the following images, every time a new search category (iPhone, Celulares e Smartphones) are added, the last item is centralized.
You will have to do it in your adapter. I have never did something like this, but my try would be something like this:
On the method onBindViewHolder:
#Override
public void onBindViewHolder(MyHolder holder, int position) {
OrderItem item = items.get(position);
//last item
if(position == item.size()-1){
holder.textview.setLayoutParams(Gravity.CENTER_VERTICAL);
}
}
Try adapt this idea in your project!