"Android" in-depth understanding of custom LayoutManager (i) series opening common pitfalls, issues, considerations, common APIs.

Source: Internet
Author: User

Reprint please indicate the source:
http://blog.csdn.net/zxt0601/article/details/52948009
This article is from: "Zhang Xudong's Blog"

This series of articles related to code portals:
Custom LayoutManager-implemented streaming layouts
Welcome to Star,pr,issue.

List of articles in this series:
Learn more about custom LayoutManager (i) series opening common pitfalls, issues, considerations, common APIs.
Deep mastery of Custom LayoutManager (ii) implementing streaming layouts (creating)

Overview

This article is the beginning of a thorough mastery of the custom LayoutManager series and is a summary report. Part of the content is not an introduction, too deep, used as a reference for the series of subsequent articles, as well as the review after browsing.

This article covers Recyclerview, LayoutManager, Recyclerviewpool, recycler.

Note:
1 The following questions, beginners, if you do not understand, you can not pay too much attention, and so finish learning custom LayoutManager related knowledge, write a few demo back to see better understanding.
2 in Recyclerview, Itemview and Viewholder are actually one by one bound, so the mentioned view = Viewholder.

A common misunderstanding, problems, precautions:

Before I start customizing the LayoutManager article, I've summed up some of the questions I've encountered in the process of learning and reading other people's articles, coding, and attaching my own understanding and answers. Welcome to shoot Brick discussion.

Because there are a lot of dabbler written on the internet LayoutManager related Chinese articles. (including I also dabbler), so many articles have been read, the mind has n questions, such as, the author is very good, but why I write alone or can not write. Does customizing a layoutmanager automatically re-use it? ... Wait, let's talk about it one by one.

Q1 finished, but I do not know how to write The Independent.

A1: Custom LayoutManager is a difficult project, and it's hard to read only one or two articles and take two or three hours to finish.
It involves the layout of the sub-view, the calculation of coordinates, the calculation of the offset, when sliding, in the appropriate time to recycle the screen is no longer displayed on the view, how to determine whether these view is not visible on the screen, and whether the view is temporarily detach off, or recycle recycled ... And so many problems
。 To be honest, maybe my level is limited, which is one of the most time-consuming knowledge points I've had in learning Android. (more than 10 hours to write the first pass of the work)
But it's worth your learning. So independent write not to lose heart, first imitate a demo write a write, if attentively understand, second time should be able to complete independently again.

Q2 Learn the basics of customizing LayoutManager: Master Custom ViewGroup.

(in the first step of the custom LayoutManager process, the onLayoutChildren() method is similar to the OnLayout () method of the custom ViewGroup.) )
However, compared with custom LayoutManager, custom ViewGroup is a static layout sub-view process, because the ViewGroup internal does not support sliding, so only need no brain layout out of all the view, you do not have to worry about the rest.
And the custom LayoutManager is different , in the first step layout, do not layout out all the sub-view, here is also some online articles in the wrong way, they take the old thought, The first step is to layout out all the Childview, which can lead to a very serious problem: your custom LayoutManager = Custom ViewGroup. That is, they do not have a view reuse mechanism .
Why Here is a simple proof of the conclusion, in Q5 's answer will explain why.
In adapter's Oncreateviewholder () method, add the print statement, if your data source has 100,000 data, then the first time Recyclerview display on the screen, Oncreateviewholder () It will be executed 100,000 times and you will be able to enjoy the ANR.
The use of the official three kinds of layoutmanager, the beginning of the screen has a few n Itemview, generally execute n times oncreateviewholder (), (it is possible to perform more than 1 times), in the subsequent sliding, In most cases, the Onbindviewholder () method is executed and no more oncreateviewholder () is executed.

Second: skilled use of recyclerview. This needless to say, after all, Recyclerview is the host of LayoutManager.

In fact, the above two points can start our learning journey, but if you can recyclerview adapter, Recyclerviewpool, Itemdecoration also have a certain understanding that is the best.

Q3 Custom LayoutManager A lot of actual combat scenes?

A3: The actual combat scene is still quite limited . The system comes with three layoutmanager already enough to meet most of the needs.

I personally learned from the study of custom LayoutManager so far, most of the understanding of the Recyclerview mechanism further deepened , but also accompanied by a certain amount of source reading experience to improve. With the bright that I imagined to be a huge productivity boost, because many times, the layout of product design requirements, existing solutions can be solved well.

but it's worth learning .

Q4 Customizing a LayoutManager to automatically reuse Itemview?

A4: No , actually this is one of the plays of the custom LayoutManager, in order to reclaim the invisible old sub view at the right time , re-use the child View Layout new Sub view, And Q2 mentioned in the LayoutManager of the initialization of the reasonable layout of the visible number of sub-view, etc., is the reuse of Itemview.
Note that the recycling here is recycle, not detach.
If you only detach itemview, and do not recycle them, they will always be saved in the Recycler mAttachedScrap , it is a ArrayList, save detach but not recycle of viewholder.

    publicfinalclass Recycler {        finalnew ArrayList<>();

(In fact, the recycler internal caching mechanism is far more than one mattachedscrap.) )

Q5 use Recyclerview is equal to Itemview reuse?

A5: apparently not . In addition to the Q4 factors, there is a big misunderstanding: many people think that the use of Recyclerview,itemview is recycled.
Here is a question: basically the app has a topbanner in, it is placed in the Recyclerview as Headerview (through the special Itemviewtype implementation), the rest are ordinary Itemview, So the list scrolls, when Banner is already invisible, will its View (viewholder) be recycled and reused by other Itemview ?
Such as:

Answer: Banner's Viewholder will be recycled , but the Viewholder's memory space will not be freed and will not be reused by other Itemview .
Recycling is well understood and LayoutManager will recycle it into recyclerviewpool when it is not visible on the screen.
However , they are not reused for Normalitem because their itemviewtype are different .
So its memory space will not be released, would have been recyclerviewpool hold, waiting for the demand of the same Itemviewtype Viewholder request arrives.
That is, when the page scrolls back to the top, when the banner is displayed, the view is reused.
Let's say why, and how to verify.

Why?

This involves recycler, recyclerviewpool knowledge, (little Amway, I am in http://blog.csdn.net/zxt0601/article/details/52267325 In the fourth section of this article, the source code of the Recyclerviewpool has been fully solved, but you can also check it yourself, the source code is very short. )
In LayoutManager, the acquisition of Childview is obtained through the following methods:

View child = recycler.getViewForPosition(i);

Inside the method, the position is first used to get the detach off Scrapview (Viewholder),

holder = getScrapViewForPosition(position, INVALID_TYPE, dryRun);

If not, then according to position to get itemviewtype,

inttype = mAdapter.getItemViewType(offsetPosition);

According to Itemviewtype to get the Viewholder in the Recyclerviewpool,

holder = getRecycledViewPool().getRecycledView(type);

Here because of our banner ViewType and Normalitem viewtype different, even if banner was recycled into the recyclerviewpool, But because Itemviewtype and ordinary itemview are different, it can not be removed, and thus reused , (diverging, another point, it can not be released , is strongly referenced in memory, http://blog.csdn.net/ zxt0601/article/details/52267325 This article is detailed analysis).
Further down because holder is still empty, the adapter Oncreateviewholder () method will eventually be called to create a new viewholder.

type);`
Verify:

Interested people to rewrite any adapter getItemViewType() method:

            @Override            publicintgetItemViewType(int position) {                return position;            }

So every itemviewtype is different, Recyclerview will not have any reuse, because every itemview in Recyclerviewpool can not find a reusable holder,itemview there are N, The Oncreateviewholder method executes n times.

See here to answer the question of Q2:
Because thecaches in Recycler (Scrapcache) and Recyclerviewpool are empty at initialization time, the Viewholder obtained at this time are all through Oncreateviewholder (), New out of the Viewholder. If get the whole itemcount number of view at this time, then also will new out itemcount number of viewholder, at this time these viewholder all exist in memory, and ordinary viewgroup no difference, also easier to oom.

A brief introduction to the caching mechanism of Q6 Recyclerview

A6: The above BB has so many, involving recycler, Recyclerviewpool and scrap,detach,remove,recycle concepts.

This picture is excerpted from the http://kymjs.com/code/2016/07/10/01, which should be in Google's official video.
I understand that the cache on the diagram is the area where the viewholder is stored, that is, the Scrapcache area, which is detach off.
This area is made up of

        final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();        ArrayList<ViewHolder> mChangedScrap = null;        final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();

These three ArrayList are made up of.
The removed Viewholder will be stored in Recyclerviewpool according to the ViewType group, and the default maximum cache is 5 per group (ViewType).

        private SparseArray<ArrayList<ViewHolder>> mScrap =                new SparseArray<ArrayList<ViewHolder>>();
Q7 the timing of detach and recycle.

A view is only temporarily erased and will be used immediately , using Detach. It will be cached into the Scrapcache area.
A view no longer appears on the screen, needs to be erased, and the next time it is displayed is unknown , use Remove. It will be grouped in ViewType and cached into the recyclerviewpool.
Note: A view is only detach, not be recycle words, will not put into Recyclerviewpool, will always exist recycler scrap. the online demo is so, so the view has not been reused, how many itemcount, will be new out of how many viewholder.

Why does the Onlayoutchildren () execute two times when Q8 is initialized?

A: See Recyclerview source code, Onlayoutchildren will execute two times, a Recyclerview onmeasure () once OnLayout ().

Li Jufu: Recyclerview's Onmeasure () will call the dispatchLayoutStep2() method, which is called internally mLayout.onLayoutChildren(mRecycler, mState); , which is the first time. As follows:

@Override    protectedvoidonMeasure(intint heightSpec) {            ......            dispatchLayoutStep2();            ......    }
    /**     * The second layout step where we do the actual layout of the views for the final state.     * This step might be run multiple times if necessary (e.g. measure).     */    privatevoiddispatchLayoutStep2() {        .....        mLayout.onLayoutChildren(mRecycler, mState);        .....    }

The OnLayout () method dispatchLayout(); is called, and the method is called internally dispatchLayoutStep2(); , and this is the second time.

Q9 based on the last question, what should we pay attention to?

A: Even when writing the Onlayoutchildren () method, also consider the view (if any) on the screen, detach off, otherwise the screen is initialized, the same position viewholder, also oncreateviewholder two times. So the ChildCount doubles as well.

The last and most important

The LayoutManager API supports powerful and complex layout recycling, and because of its strong API, we need to implement a lot of code to complete the functionality. Do not over-encapsulate, over-optimize your code, as long as you can complete your needs. ( of course the most basic requirements: Viewholder multiplexing to meet )
The exact words are as follows:

Article Link: http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/
This article is the best material I have ever seen to learn custom LayoutManager.

Two common APIs: Layout API:
//找recycler要一个childItemView,我们不管它是从scrap里取,还是从RecyclerViewPool里取,亦或是onCreateViewHolder里拿。View view = recycler.getViewForPosition(xxx);  //获取postion为xxx的View
addView(view);//将View添加至RecyclerView中,addView(child, 0);//将View添加至RecyclerView中,childIndex为0,但是View的位置还是由layout的位置决定,该方法在逆序layout子View时有大用
measureChildWithMargins(scrap, 0, 0);//测量View,这个方法会考虑到View的ItemDecoration以及Margin
//将ViewLayout出来,显示在屏幕上,内部会自动追加上该View的ItemDecoration和Margin。此时我们的View已经可见了layoutDecoratedWithMargins(view, leftOffset, topOffset,                        leftOffset + getDecoratedMeasuredWidth(view),                        topOffset + getDecoratedMeasuredHeight(view));
Recycle API:
detachandscrapattachedviews ( recycler) ; //detach lightweight recycle all View  detachandscrapview (view, recycler) ; //detach Lightweight collection Specify view  //recycle really recycle a view, the view comes back again need to execute Onbindviewholder method  removeandrecycleview (View Child, recycler recycler)  removeandrecycleallviews (recycler recycler) ;  
detachView(view);//超级轻量回收一个View,马上就要添加回来attachView(view);//将上个方法detach的View attach回来recycler.recycleView(viewCache.valueAt(i));//detachView 后 没有attachView的话 就要真的回收掉他们
Moving Sub Viewapi:
offsetChildrenVertical(-dy)// 竖直平移容器内的item offsetChildrenHorizontal(-dx);//水平平移容器内的item
Tool API:
publicintgetPosition(View view)//获取某个view 的 layoutPosition,很有用的方法,却鲜(没)有文章提及,是我翻看源码找到的。
Here's how we'll consideritemdecoration, but some functions do not consider the existence of a marginGetdecoratedleft(view)=View.GetLeft()Getdecoratedtop(view)=View.GetTop()Getdecoratedright(view)=View.GetRight()Getdecoratedbottom(view)=View.Getbottom()Getdecoratedmeasuredheight(view)=View.Getmeasuredwidth()Getdecoratedmeasuredheight(view)=View.Getmeasuredheight()
//Because the above method does not consider the existence of margin, so I refer to Linearlayoutmanager Source:    /** * Gets the space occupied by a childview in the horizontal direction * * @param View * @return  */     Public int Getdecoratedmeasurementhorizontal(View view) {FinalRecyclerview.layoutparams params = (recyclerview.layoutparams) view.getlayoutparams ();returnGetdecoratedmeasuredwidth (view) + Params.leftmargin + params.rightmargin; }/** * Gets the space occupied by a childview in the vertical direction * * @param View * @return  */     Public int getdecoratedmeasurementvertical(View view) {FinalRecyclerview.layoutparams params = (recyclerview.layoutparams) view.getlayoutparams ();returnGetdecoratedmeasuredheight (view) + Params.topmargin + params.bottommargin; }

"Android" in-depth understanding of custom LayoutManager (i) series opening common pitfalls, issues, considerations, common APIs.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.