Android: Use the viewholder Luke, and Larry, and curly, And Moe

Source: Internet
Author: User

This is going to be a quick hit blog post about the android
"Viewholder" pattern. This is a pattern that contains people seem to be
Least vaguely familiar with, but not very using actually use (based on
Open source Android applications and examples/books, etc .).

First some background. Larry, Moe, and curly were characters from ..
. OK, not that much background, but to really make use of
Viewholder with Android you do need to know what the listview widget is (a helper for managing views of lists), and that listviews and generally backed by adapters
(Adapters provide data for lists and build views for said data, they
Can be made from lists of stuff in files, or from in memory arrays, or
From databases, and so on ).

An example of a listview in action is seen in the screen shot below.

This screen is taken from the devnexus 2010
Demo Application I wrote for a conference I attended and spoke at this
Year. This participating listview is basically a navigable LIST OF
Presentation into acts and speakers. We will look at the code behind
This screen, complete with viewholder, coming up. First a bit more
Background.

You are probably at least vaguely familiar with listview/adapter and
The related concepts if you have done any android development at all.
Listview is * very * powerful and helpful widget. Nevertheless, listview's
Are often misused and abused because there are so many options and
Settings and patterns that surround them. I don't have time to go
Great Depth on listview itself, but for the quick hit I promised I want
To address 2 key things to keep in mind when working with listviews:

  • Creating views is expensive, you don't want to inflate or manually
    Create new views for every view on the list. listview can re-use views,
    If you let it.
  • Even if you are re-using views, you also don't want to find child
    Views by ID (findviewbyid) every time, because that is expensive too.
  • I wocould say that 90% of Android examples or open source apps I see
    (or developers I talk to) do the first item there properly. depending on
    the adapter in play they are re-using views. it's pretty simple, use
    the "convertview" on simple adapters like arrayadapter (which we will
    see coming up) and use the "newview" on more involved adapters like
    cursoradapter. I wocould also say that the same high percentage of
    examples and open source apps * Do not * use the viewholder to avoid trips
    to findviewbyid. if your list is small, this might not be a big deal,
    but if the list is large it can make a difference in terms of frame
    rate, resource usage, and performance (which equals better experience
    for the user, longer battery life, etc .). also, it's a good habit to be
    in even with small lists, more efficient code is better, especially on a
    mobile platform.

    So how do you do this stuff? Well, here is the adapter from the aforementioned devnexus 2010 application to demonstrate:

    01 Static Class Viewholder {
    02 Private Textview view1;
    03 Private Textview view2;
    04 }
    05  
    06 Private Class PresentationadapterExtends Arrayadapter <presentation & G <WBR> T ;{
    07  
    08 Layoutinflater Vi = (layoutinflater) presentationlist.This. Getsyste <WBR> mservice (context. layout_inflat <WBR> er_service );
    09 Private Final Arraylist <presentation> presentations;
    10  
    11 Public Presentationadapter (Final Context context,Final Int Resid,Final Arraylist <presentation> presentations ){
    12 Super(Context, resid, presentations );
    13 This. Presentations = presentations;
    14 }
    15  
    16 @ Override
    17 Public View getview (Final Int Position,Final View convertview,Final Viewgroup parent ){
    18 // Re-use the convertview, try not to recreate objects here or inflate every time (expensive)
    19 // Also use the "tag" with the "view holder" pattern to avoid findviewbyid every time
    20 View v = convertview;
    21 If (V =Null){
    22 V = VI. Inflate (R. layout. list_items <WBR> _ item,Null);
    23 Viewholder =New Viewholder ();
    24 Viewholder. view1 = (textview) v. findviewbyid (R. Id. list_item _ <WBR> above );
    25 Viewholder. view2 = (textview) v. findviewbyid (R. Id. list_item _ <WBR> below );
    26 V. settag (viewholder );
    27 }
    28  
    29 Presentation P = presentations. Get (position );
    30 If (P! =Null){
    31 Viewholder = (viewholder) v. gettag ();
    32 Viewholder. view1.settext (P. Nam <WBR> E );
    33 Viewholder. view2.settext (P. SPE <WBR> Aker );
    34 }
    35 Return V;
    36 }
    37 }

    The complete code for the devnexus application (for context), is here.
    What we are focusing on above is the adapter to the listview. Within it
    We see that we are making use of the convertview if present to grab our
    Subsequent views, and to populate our own internal viewholder
    Representation. If the convertview isn' t present, then we do the extra
    Work of inflating our views and building our viewholder.

    The "convertview" is a convenient helper object provided to you
    The framework specifically for re-use (if the framework is ready
    Provide it, the first item in the list will have a null convertview,
    Hence the check, and the work only if it is null). The framework knows
    The views that are passing by, and as it recycles them it hands you one
    That you can "Convert ."

    So what is the viewholder? Well, that's really just a simple object
    We have created (using a package scoped inner class) that stores child
    Views (though you cocould store anything there, that is all we need
    This example). view objects have a "tag" property that you can use
    Store any object. If you are getting recycled views anyway, it's very
    Easy and helpful to just stick child views you need * There * and retrieve
    Later, as opposed to calling "findviewbyid" to pull views from
    Resources for every view in the list. Really this just saves us
    Findviewbyid CILS. That might not seem like much, but again, in large
    Lists It can cut down on overhead.

    A little further down in the code, after we get past creating
    Convertview in the case that it's null, we see where we use
    Viewholder to get a reference to our subsequent child views, and set
    Stuff (in this case just strings, but cocould be anything ).

    This is a simple example, and I certainly won't promise that it's
    Perfect, but hopefully it does help to explain what viewholder is, and
    Why it's useful (and a little about re-processing ing views in general ).

    Comments alternative to the viewholder submitted by Uncle code monkey (not verified) on Tue, 12/21/2010-10:54.

    Thanks for writing on this subject. In the past, I did not bother
    With caching the find results and after reading this blog, I decided
    Give it a try and see if it improves the speed of my app any. I noticed
    My app become more responsive and that's all the convincing I need
    Keep it.

    I do, however, have a different approach to caching than how you
    Wrote this article. Instead of keeping a separate class in which
    Store the result of the varous finds, I just store it directly into
    View. Tag mechanic like so:

    1 Protected Object getviewhandle (view aparentview,Int Aviewtofind ){
    2 Object v = aparentview. gettag (aviewtofind <WBR> );
    3 If (V =Null){
    4 V = aparentview. findviewbyid (aview <WBR> tofind );
    5 Aparentview. settag (aviewtofind <WBR>, V );
    6 }
    7 Return V;
    8 }

    And then call it in my code

    1 Textview TV = (textview) getviewhandle (itemvi <WBR> EW, R. Id. some_text_view );

    This way I don't need to define classes for each kind of item view in
    The list and makes the technique easily adaptable for different lists
    Without introducing another class that needs to be passed around to all
    The code that works with such views.

    thanks for the inspiration!

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.