[Android] Cache multiplexing of Recyclerview

introduce

RecyclerView is a highly customizable list view component commonly used in Android development. It is improved and enhanced on the basis of ListView and GridView, aiming to provide better performance and more flexible layout management.

The main features of RecyclerView are as follows:

灵活的布局管理器(LayoutManager):
RecyclerView uses LayoutManager to manage how its subviews are laid out. Different LayoutManagers can achieve different layout effects, such as linear layout, grid layout, waterfall flow layout, etc. You can choose a suitable LayoutManager or customize the LayoutManager according to your needs.

高效的回收再利用机制:
RecyclerView handles the recycling and reuse of subviews through Recycler. When subviews slide off screen, RecyclerView recycles them and marks them for reuse. This reduces memory usage and improves performance.

分离的ViewHolder模式:
RecyclerView uses the ViewHolder pattern to manage the data binding of subviews. By creating a ViewHolder to store references to subviews, you can avoid frequent findViewById operations and improve the rendering efficiency of list items.

动画支持:
RecyclerView provides animation support for list items. You can set ItemAnimator to achieve animation effects when adding, deleting, moving and other operations, adding interaction and visual effects to the list.

事件拦截与处理:
RecyclerView supports event interception and processing, and can monitor and process subview click, long press, slide and other events, and perform corresponding operations as needed.

RecyclerView nested sliding

1. When the nested sliding of RecyclerView starts, dispatchNestedPreScrollthe method will be called to notify the parent container of the upcoming sliding event. This is to give the parent container (such as the outer ScrollView or NestedScrollView) a chance 对滑动事件进行预处理.

2. After dispatchNestedPreScroll, RecyclerView will call scrollByInternalthe method to scroll. The scrollByInternal method will 计算滚动的偏移量, and apply it to the content of the RecyclerView.

3. Next, RecyclerView will call dispatchNestedScrollthe method to notify the parent container 滑动的实际情况, including information such as the distance and direction of the slide. The parent container can perform corresponding processing based on this information, such as triggering edge effects.

4. After the dispatchNestedScroll method, RecyclerView will call scrollStepthe method, which contains 滚动的水平和垂直偏移量. The scrollStep method will call LayoutManagerthe scrollHorizontallyByand scrollVerticallyBymethod to achieve specific scrolling effects.

5.scrollHorizontallyBy and scrollVerticallyBy are the internal methods of LayoutManager, which are responsible for specific handling 水平和垂直滚动. They update the position of the visible views in the RecyclerView according to the offset.

6. During the scrolling process, LayoutManager will call layoutChunkthe method 填充新的可见视图. In this process, RecyclerView will call recycler.getViewForPosition方法to get the view at the specified position, and use measureChildWithMarginsthe method to measure the size of the view.

7. The measureChildWithMargins method is used to measure the size of each RecyclerView 可见视图. It takes into account the view's padding, marginand and inset(分割线的空间)other factors to ensure that the view can be correctly laid out in the RecyclerView.

Fill method

The fill method in RecyclerView is the core method used to fill the visible view. When the RecyclerView is scrolling, the fill method will be called repeatedly to fill the new visible view according to the scroll direction and scroll offset.

The main logic of the fill method:

1. First, the fill method will 滚动方向be obtained according to (vertical or horizontal) RecyclerView的布局状态(LayoutState), and the layout state contains some key information, such as the currently visible position, offset, etc.

LayoutManager2. Then, the fill method will call the method to get the next nextsubview to be filled according to the information in the layout state . LayoutManager will select the appropriate subview according to the current layout state and the view in the recycling pool (Recycler) and return it to the fill method.

3. Next, the fill method will call measureChildWithMarginsthe method of LayoutManager to measure the subview. This method will take into account factors such as subviews padding, marginand and insetso on, to ensure that the subviews can be correctly laid out in the RecyclerView.

4. Then, the fill method will call LayoutManagerthe layoutDecoratedmethod to lay out the subviews. The layoutDecorated method will set the position and size of the subview, and place it correctly in the specified position in the RecyclerView.

5. After filling a subview, the fill method will 更新布局状态include some information, such as the currently visible position, offset, etc.

6. Next, the fill method will 判断是否填充完所有可见位置的子视图. If there are still unfilled positions, the fill method will 继续进行下一轮的填充.

Through this 不断调用fill方法, RecyclerView can dynamically fill new visible views that appear during the scrolling process, and recycle invisible views that have rolled off the screen, achieving efficient scrolling and view reuse.

It should be noted that the specific implementation of the fill method is defined by LayoutManager, and different LayoutManagers may have different implementation logic. When customizing LayoutManager, the fill method can be overridden to meet specific layout requirements.

RecyclerView's multi-level cache

mChangeScrap与 mAttachedScrap

mChangedScrap: This list is used for 缓存仍然在屏幕内但【数据发生变化】的ViewHolder. When the RecyclerView performs the layout process, it marks the ViewHolders whose data has changed and adds them to mChangedScrap so that the data can be rebinded later.

mAttachedScrap: This list is used for 缓存仍然在屏幕内且可见的ViewHolder. As the RecyclerView scrolls, newly incoming ViewHolders on the screen are added to mAttachedScrap for layout and databinding later.

ViewHoldermCachedViews

This list is for 缓存已经离开屏幕的ViewHolder. When the RecyclerView is scrolled, the ViewHolder that is removed from the screen is added to it mCachedViews. These ViewHolders are cached so that they can be quickly reused when needed without having to be recreated.

ViewHoldermViewCacheExtension

This mechanism allows developers 自定义视图的缓存和复用逻辑. Through implementation ViewCacheExtension接口, developers can specify a specific type of view caching method to improve reuse efficiency.

RecycledViewPool

This is a global one ViewHolder缓存池. When RecyclerView cannot find a reusable ViewHolder from other cache lists, it will try to get it from RecycledViewPool. This buffer pool can be reused across different types of ViewHolders to improve the overall reuse efficiency.

When RecyclerView recycles and reuses ViewHolder, it uses the following key data structures:

mCachedViews:
This is one ArrayList, for 缓存已经离开屏幕的ViewHolder. RecyclerView 默认情况下会为该列表分配2个ViewHolder的空间, that is DEFAULT_CACHE_SIZE = 2. If the list is full, the oldest ViewHolder will be removed. You can also use setViewCacheSizemethod to set the size of this cache list.

scrapHeap:
This is also one ArrayList, used for 存放回收池中的ViewHolder. The recycling pool is global and used by the entire RecyclerView. RecyclerView 默认情况下会为该列表分配5个ViewHolder的空间, that is DEFAULT_MAX_SCRAP = 5. When the ViewHolder needs to be reused, first try to obtain the ViewHolder from the recycling pool. method can be used setMaxRecycledViewsto set the maximum number of ViewHolders in the recycling pool.

mScrap:
This is a SparseArray for 存储不同类型ViewHolder的回收数据. It is a 整数作为键(viewType)的映射表, one for each key ScrapData对象. ScrapData object 包含了该类型ViewHolder的回收池(mScrapHeap). In this way, RecyclerView can 针对不同的ViewHolder类型进行缓存和复用.

What is cache reuse for? What is saved?

For the cache reuse of ViewHolder, it is aimed at different types of ViewHolder. What is saved is the ViewHolder that has been created and no longer needs to be displayed on the screen for the time being.

Specifically:

缓存池中复用ViewHolder(从回收池中获取):
When a new ViewHolder needs to be created, it will first try to obtain the corresponding type of ViewHolder from the recycling pool. The recycling pool is a pool used to cache created ViewHolders. If there is a ViewHolder available in the recycling pool, it can be reused directly without recreating it. This process will call onBindViewHoldermethods to update the data and interface of ViewHolder.

从缓存视图列表中复用ViewHolder:
If there is no ViewHolder available in the recycling pool, it will try to get it from the cached view list. The cached view list is a list specially used to cache ViewHolders that leave the screen, storing a certain number of ViewHolders. If you successfully get a reusable ViewHolder from the list, you can use it directly without recreating it, and it is also a 无需调用onBindViewHoldermethod, because this ViewHolder has been displayed and bound to data before.

If the reusable ViewHolder cannot be obtained from the above two places, onCreateViewHolderthe method will be called, a new ViewHolder instance will be created, and onBindViewHolderthe data and interface will be bound through the method.

To sum up, the cache reuse mechanism of ViewHolder saves the ViewHolder instances that have been created and no longer need to be displayed temporarily by recycling the pool and cache view list. This can avoid frequent creation and destruction of ViewHolder, and improve the performance and efficiency of RecyclerView.

Guess you like

Origin blog.csdn.net/qq_43358469/article/details/131912195