I use a RecyclerView to display a list of items. The RecyclerView shows a single item at the time. By clicking a button I would like to change ViewHolders for all the items, including the one displayed. The data stays the same, only the list item layout changes.
I supposed I need to clear the cache pool, but it did not help. There are still views in the recycler pool.
recyclerView.recycledViewPool.clear()
RecyclerView keeps using the cached views.
Moreover, how to re-create the view with a new ViewHolder of the item displayed?
add type in your model class
var viewType : ViewType
make an enum of viewType
ViewType { VIEW_ONE, VIEW_TWO }
override ItemViewType function in your RecyclerViewAdapter. Make separate Layout files for each view type and create/inflate in onCreateViewHolder of RecyclerViewAdapter.
When button is being pressed. Change the ViewType in your model class and call notifyDatasetChanged()
Related
I have a use case...
I want to get layoutInflator to bind different Views for nested recyclerView. Is there any best way to get layoutInflator?
I was trying to get it from onBindViewHolder
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder. //something?
}
You shouldn't be inflating anything in onBindViewHolder - onCreateViewHolder is where you set up a ViewHolder object that displays a list item, including inflating its layout views. onBindViewHolder is where you interact with those views, to display the appropriate data for the current item.
Those created ViewHolders get reused, so instead of inflating views for every item, you just create a handful of ViewHolders that get swapped around as you scroll the list. That recycling of a pool of VHs is why it's called a RecyclerView.
Generally, you'd store references to the inflated views inside each ViewHolder, like in this example:
/**
* Provide a reference to the type of views that you are using
* (custom ViewHolder)
*/
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView
init {
// Define click listener for the ViewHolder's View
textView = view.findViewById(R.id.textView)
}
}
That way, the ViewHolder that gets passed into onBindViewHolder has a textView field you can access, e.g. to set its text contents to display data for the current item. (If you're using View Binding, you could store a reference to the binding object instead, and access the views through holder.binding.textView etc)
I don't know what you're doing with nested RecyclerViews, but the principle is the same - each ViewHolder in the main RV will contain another RV, with its own adapter and data set, created and initialised in onCreateViewHolder. If you want to change its contents (because you're displaying a particular item in the main RV list) you'd probably want to add a setData function on the nested RV's adapter that changes its data set and refreshes the display. Let the adapter handle inflating things when it needs to, inside onCreateViewHolder
I have implemented multiple view type recycler view but I want to implement single selection for each view type as shown in image below
MultipleviewSingleSelectionForEachType
What you're looking for is a Heterogeneous list with(in your case) a header and list items.
This is very easy to implement with a recyclerview using a Heterogeneous adapter(this is now very easy with view holder pattern).
As far as the selection is concerned, what you can do is save the selection in the arraylist, if the size of the arraylist is zero, implement a onLongClickListener on the list item viewType, and if the size is greater than zero, then just implement a normal click listener, and on successive selection store each list object type in that arraylist.
I have a ViewHolder that contains another RecyclerView. This type of the ViewHolder gets reused multiple times.
Since the ViewHolder is shared between different items, the scroll position of the RecyclerView is also shared between items. Eg, You scroll to the end of the first item, the fifth item's RecyclerView also gets scrolled to the very end, because the view is reused.
I'm trying to solve this by mapping 1 ViewHolder to 1 item.
I've tried to set an itemId for the item, call RecyclerView.ViewHolder#setIsRecyclable(false), and extend/set RecyclerView.getRecycledViewPool().setMaxRecycledViews() as mentioned in this answer
After I scroll down and scroll back up (The ViewHolder gets recycled), the scroll position of the inner RecyclerView is reset to the first item.
I would like to know what is the right way to implement a footer in RecyclerView which can be used to display different views. Few examples are as below
View for network error with a button to reload.
View when data is loading from server with a progress bar.
View when there is no more data available.
And so on.
I came across https://stackoverflow.com/a/29168617/371557 which mentions that I have to Override getItemViewType and inflate different views in onCreateViewHolder
What I do not understand is how will RecyclerView know which ViewType it has to request for? How can I force the RecyclerView to show the ViewType?
RecyclerView is the new view more powerfull than listview, you can make a footer in this but it's for me not the right way.
I recommend to create a layout include your RecyclerView and add a dedicated view like Snackbar or a custom footer.
For your question, the RecyclerView knows what to display with the getItemViewType(int positionItem) method.
For example, if the item in position 6 must be shown in the list, getItemViewType return the id of view in onCreateViewHolder(ViewGroup viewGroup, int id) method and recycle the view which could already be used in list for saving memory.
(Sorry for my poor English :)
I have a RecyclerView with a list of items. The individual list item is an ImageView with a TextView. They have different behaviours when clicked. The individual list item is rendered with the aid of a ViewHolder.
Where should I put the .setOnClickListener() call for the ImageView and TextView? In the ViewHolder? Or inside the RecyclerView's onBindViewHolder method when the view is binded?
From the official doc of ViewHold:
A ViewHolder describes an item view and metadata about its place
within the RecyclerView.
So you should avoid do anything else in the viewhold, instead use onBindViewHolder in the RecyclerView
If you take a look at the example made by Google of RecyclerView on GitHub you will see google does not set listeners in the ViewHolder
Call it inside of the onBindViewHolder method while you're binding your ImageView and TextView. If you set it on the ViewHolder itself, then the onClick() will be triggered for the entire list item in the RecyclerView .