Android ListView Works fully parsed (transferred from Guo Lin teacher Blog)
Source: Internet
Author: User
<span id="Label3"></p><p><p>Original Address: http://blog.csdn.net/guolin_blog/article/details/44996879</p></p><p><p></p></p><p><p>Of all the common native controls on android, the most complicated usage should be the listview, which is designed to handle a lot of content elements that the phone screen cannot display. The ListView can use the form of a list to present content, and the content beyond the screen can be moved to the screen by swiping through the Finger.</p></p><p><p></p></p><p><p>In addition the ListView has a very magical function, I believe everyone should have experienced, even if the ListView load very much data, such as hundreds or even more, the ListView will not occur oom or crashes, and as we swipe to browse more data , the memory consumed by the program does not grow. So how does the ListView implement such a magical function? At the beginning I took a study of the mentality of a long time to take the source of the ListView read through, the basic understanding of its working principle, in the exclamation of Google God can write such exquisite code at the same time I also have a awe, because the ListView code volume is larger, the complexity is very high, It was difficult to express clearly in words, so I gave up the idea of writing it as a blog Post. So now in retrospect this matter I already had the guts to regret the green, because did not have a few months time I had combed the original clear source and forgot Cleanly. So now I re-set the heart again to the source of the ListView reread again, then this time I must write it a blog, share to everyone's as well as my own notes it.</p></p><p><p>Let's first look at the inheritance structure of the listview, as shown in:</p></p><p><p></p></p><p><p></p></p><p><p>As you can see, the inheritance structure of the ListView is quite complex, it is directly inherited from the abslistview, and Abslistview has two sub-implementation classes, one is the listview, the other is the gridview, so we can guess from this point, Both the ListView and the GridView have a lot in common in their working principles and implementations. Then abslistview inherit from Adapterview,adapterview and inherit from viewgroup, and the following is what we are familiar With. Let's take a look at the inheritance structure of the ListView and later help us to analyze the code more CLEARLY.</p></p><p><p></p></p><p><p></p></p>The role of Adapter<p><p></p></p><p><p>Adapter believe that we are not unfamiliar, we usually use the ListView when it will be used. So then, have you ever thought about why you need to adapter this thing? The general feeling is that the use of Adapter,listview has become much more complex than other controls. So here we go first to learn what the adapter really played a role.</p></p><p><p></p></p><p><p>In fact, the control is to interact with the display of data, but the ListView is more special, it is to show a lot of data use, but the ListView only assume the interaction and display work, as to where the data comes from, the ListView does not care. therefore, the most basic mode of the ListView that we can envision is to have a ListView control and a data source.</p></p><p><p></p></p><p><p>But if the ListView and the data source are really working directly, the ListView is going to do a lot of matching Work. Because the concept of the data source is too vague, we only know that it contains a lot of data, as to what the data source is exactly what type, and there is no strict definition, there may be an array, it may be a collection, and possibly even the database table query out of the Cursor. So if the ListView really go for each kind of data source to do the appropriate operation, one is that the extensibility will be poor, built-in several adaptations only a few adaptation, can not be added dynamically. The second is beyond the scope of its own responsibility, no longer just assume the interaction and display work, so the ListView will become more Bloated.</p></p><p><p></p></p><p><p>Then obviously the Android development team will not allow such a thing to happen, so there is a mechanism such as adapter. As the name implies, adapter is the meaning of the adapter, which plays a bridge between the ListView and the Data source, and the ListView does not work directly with the data source, but instead accesses the real data source with adapter, which differs from the previous Adapter interfaces are unified, so the ListView no longer has to worry about any adaptation aspects. and adapter is an interface (interface), it can implement a variety of subclasses, each subclass can go through their own logic to complete the specific function, as well as with the specific data source adaptation operation, For example, Arrayadapter can be used for arrays and list types of data source adaptation, Simplecursoradapter can be used cursor type of data source adaptation, so it is very clever to solve the problem of the data source adaptation difficult, and also has a fairly good extensibility. The simple principle is as follows:</p></p><p><p></p></p><p><p>of course, the role of adapter is not only the data source adaptation, there is a very very important method also need to be rewritten in the adapter, that is GetView () method, which is described in detail in the following article.</p></p><p><p></p></p>RecycleBin mechanism<p><p> So before we begin to analyze the source of the listview, there is one thing we need to know in advance, which is the RecycleBin mechanism, which is one of the most important reasons for the ListView to be able to achieve hundreds of thousands of data without oom. In fact, recyclebin code is not many, only about 300 lines, it is written in the abslistview of an internal class, so all inherited from the Abslistview subclass, that is, the ListView and the gridview, can use this Mechanism. So let's take a look at the main code in recyclebin, as Follows: </p></p><pre class="brush:java;gutter:true;">/** * The RecycleBin facilitates reuse of views across Layouts. The RecycleBin * has a levels of storage:activeviews and Scrapviews. Activeviews is * Those views which were onscreen at the start of a Layout. by * construction, They is displaying current Information. At the end of "layout", all views in Activeviews is demoted to Scrapviews. Scrapviews * is old views that could potentially is used by the adapter to avoid * allocating views unnecessarily. * * @see android.widget.abslistview#setrecyclerlistener (android.widget.AbsListView.RecyclerListener) * @see Android.widget.AbsListView.RecyclerListener */class recyclebin {private Recyclerlistener mrecyclerlistener;/** * the Position of the first view stored in Mactiveviews. */private int mfirstactiveposition;/** * Views this were on screens at the start of Layout. This array was * populated at the start of layout, and at the end of layout all view * In Mactiveviews be moved to MSCRAPV Iews. Views in Mactiveviews * represent a contIguous range of views, with position of the first * view store in Mfirstactiveposition. */private view[] mactiveviews = new view[0];/** * unsorted views that can is used by the adapter as a convert VIEW. */private arraylist<view>[] mscrapviews;private int mviewtypecount;private arraylist<view> mCurrentScrap ;/** * Fill activeviews with all of the children of the ABSLISTVIEW. * * @param childCount * The minimum number of views mactiveviews should hold * @param firstactiveposition * The position of the first view that would be is stored in * mactiveviews */void fillactiveviews (int CHILDC ount, int Firstactiveposition) {if (mactiveviews.length < ChildCount) {mactiveviews = new view[childcount];} Mfirstactiveposition = firstactiveposition;final view[] activeviews = mactiveviews;for (int i = 0; i < childCount; i++) {View child = Getchildat (i); Abslistview.layoutparams LP = (abslistview.layoutparams) child.getlayoutparams ();//Don ' t put header or FOoter views into the scrap heapif (lp! = null && lp.viewtype! = item_view_type_header_or_footer) {//note:we do p Lace Adapterview.item_view_type_ignore in//active views.//however, We won't place them into scrap views.activeviews[i ] = child;}}} /** * Get The view corresponding to the specified Position. The view would * was removed from mactiveviews if it is found. * * @param position * The position to look up in Mactiveviews * @return The view if it is found, null Otherwis E */view getactiveview (int position) {int index = position-mfirstactiveposition;final view[] activeviews = mactiveviews; If (index >= 0 && Index < Activeviews.length) {final View match = activeviews[index];activeviews[index] = Nu Ll;return match;} Return null;} /** * Put A view into the Scapviews List. These views is Unordered. * * @param scrap * The view to add */void addscrapview (view SCRAP) {abslistview.layoutparams LP = (abslistview . Layoutparams) Scrap.getlayoutparams (); if (lp = = Null) {return;} Don ' t put the header or footer views or views that should is ignored//into the scrap heapint viewtype = lp.viewtype;if (!s Houldrecycleviewtype (viewtype)) {if (viewtype! = item_view_type_header_or_footer) {removedetachedview (scrap, false);} return;} if (mviewtypecount = = 1) {dispatchfinishtemporarydetach (scrap); mcurrentscrap.add (scrap);} else { Dispatchfinishtemporarydetach (scrap); Mscrapviews[viewtype].add (scrap);} If (mrecyclerlistener! = Null) {mrecyclerlistener.onmovedtoscrapheap (scrap);}} /** * @return A View from the Scrapviews Collection. These is Unordered. */view getscrapview (int position) {arraylist<view> scrapviews;if (mviewtypecount = = 1) {scrapviews = mCurrentScrap ; int size = Scrapviews.size (); if (size > 0) {return scrapviews.remove (size-1);} Else {return null;}} else {int whichscrap = Madapter.getitemviewtype (position), if (whichscrap >= 0 && Whichscrap < MSCRAPVIEWS.L Ength) {scrapviews = mscrapviews[whichscrap];int size = SCRapviews.size (); if (size > 0) {return scrapviews.remove (size-1);}} Return null;} public void Setviewtypecount (int viewtypecount) {if (viewtypecount < 1) {throw new illegalargumentexception ("Can ' t hav e a Viewtypecount < 1 ");} Noinspection uncheckedarraylist<view>[] scrapviews = new Arraylist[viewtypecount];for (int i = 0; i < ViewType Count; I++) {scrapviews[i] = new Arraylist<view> ();} Mviewtypecount = Viewtypecount;mcurrentscrap = Scrapviews[0];mscrapviews = scrapviews;}}</pre><p><p></p></p><p><p>The RecycleBin code here is not all, I just put out the most important methods. So let's start with a simple interpretation of these methods, which will help to analyze how the ListView works Later.</p></p> <ul> <li><li><strong>fillactiveviews ()</strong> This method receives two parameters, the first parameter represents the number of view to store, and the second parameter represents the position value of the first visible element in the LISTVIEW. RecycleBin uses the Mactiveviews array to store the view, which, when called, stores the specified element in the ListView into the Mactiveviews array, based on the parameters passed IN.</li></li> <li><li><strong>GetActiveView ()</strong> This method corresponds to Fillactiveviews (), which is used to obtain data from the Mactiveviews array. The method receives a position parameter that represents the position of the element within the ListView and automatically converts the position value to the subscript value corresponding to the Mactiveviews array. Note that the view stored in the mactiveviews will be removed from the mactiveviews once it is acquired, and the next time the view of the same location will return null, which means mactiveviews cannot be reused.</li></li> <li><li><strong>Addscrapview ()</strong> is used to cache an obsolete view, which receives a view parameter and, when a view is determined to be discarded (such as scrolling out of the screen), this method should be called to cache the VIEW. RecycleBin uses the two lists of Mscrapviews and mcurrentscrap to store obsolete VIEW.</li></li> <li><li><strong>Getscrapview</strong> is used to remove a view from the discarded cache, and the view in these discarded caches is not sequential, so the algorithm in the Getscrapview () method is very simple, is to return a scrap view that gets the tail directly from the MCURRENTSCRAP.</li></li> <li><li><strong>Setviewtypecount ()</strong> We all know that adapter can rewrite a getviewtypecount () to indicate that there are several types of data items in the listview, and Setviewtypecount () The function of a method is to enable a separate RecycleBin caching mechanism for each type of data item. In fact, the Getviewtypecount () method is not usually used in many ways, so we just need to know that there is a function in the Recyclebin.</li></li> </ul><p><p></p></p><p><p>After understanding the main methods in RecycleBin and their usefulness, the following can begin to analyze how the ListView works, here I will still follow the way of analyzing the source code before, that is, follow the main line execution process to gradually read and point to stop, otherwise, This article will be a long, long time if you post all the code in the LISTVIEW.</p></p><p><p></p></p>Layout for the first time<p><p>anyway, the listview, even if it is special eventually inherited from the view, so its execution process will also follow the rules of the view to execute, for this kind of unfamiliar friends can refer to my previous written <strong>Android view drawing process fully resolved, Take you</strong> step-by-step in-depth understanding of view (ii).</p></p><p><p></p></p><p><p>The execution process of the view is divided into three steps, onmeasure () is used to measure the size of the view, onlayout () is used to determine the layout of the view, and OnDraw () is used to draw the view to the Interface. In the listview, onmeasure () has no special place, because it is a view, occupies the most space and is usually the whole Screen. OnDraw () is also meaningless in the listview, because the ListView itself is not responsible for drawing, but is drawn by the child elements in the LISTVIEW. So the most magical features of the ListView are actually in the OnLayout () method, so this article is also the main analysis of the content of this method.</p></p><p><p></p></p><p><p>If you go to the ListView source to find, you will find that the ListView is not onlayout () this method, because this method is implemented in the parent class Abslistview of the listview, the code is as Follows:</p></p><p><p></p></p><p><p>Android ListView Works fully parsed (transferred from Guo Lin teacher Blog)</p></p></span>
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