Advanced Android--adapter in-depth understanding and optimization

Source: Internet
Author: User

Advanced Android--adapter in-depth understanding and optimization


typically for a multiple-element-containing View , such as ListView , GridView , Expandablelistview , the time we were to set it to a Adapter . Adapter is a bridge that provides data to and from view, and is also a view bridge that provides each Item .

in ListView as an example, it works as :

● ListView for List in each Item , Adapter will call a GetView method to get a layout view

● we will generally Inflate a new View , populates the data and returns the display

Of course, if our Item A lot of words (like tens of thousands) will create a new View it? Obviously this memory is not acceptable,Google will not do so,Android has a component called recycler , That's how he works:

Obviously, no matter how many item is in the data, recycler only stores the view in memory that is visible on the display. When you swipe down, the top invisible item moves directly back to the bottom to fill the data again into the new item. This way, you don't have to create a new view every time.

This is the invocation of the GetView method that we have common in adapter, and we can see that Convertview is the layout view of each item before Recyler.

Public View GetView (int position, view Convertview, viewgroupparent)


So, Android has provided us with a recycler mechanism, we should use this mechanism, not every time Inflate a View .

Example

Don ' t

Public View GetView (int position, view Convertview, viewgroupparent) {    Convertview = Layoutinflater.from (Mcontext). Inflate (r.layout.item_view,null);    dosomething ... return Converview;}


Do

Public View GetView (int position, View Convertview, viewgroupparent) {     if (Convertview ==null) {           Convertview = Layoutinflater.from (Mcontext). Inflate (R.layout.item_view, null);     }    dosomething ... return Converview;}


The role of Viewholder

The recycler model mentioned earlier is to solve the waste of view resources caused by repetitive inflate, and what methods can we optimize our performance again? The answer is yes.

We still from the GetView in each method call to see, we found that in fact, when we get convertview, each time will be based on this layout to Findviewbyid. As below, make our usual notation:

if (Convertview = = null) {                 Convertview = minflater.inflate (R.layout.item_view, null);          } TextView Titletextview = (TextView) Convertview.findviewbyid (R.id.text));         ImageView Iconimageview = (ImageView) convertview.findviewbutid (R.id.icon)); DoSomething ...




Findviewbyid is in the analysis of the Layout.xml layout of the sub-view, parsing XML is a definitely work, so Google also suggested that we optimize the thankless of the work, so put forward the concept of viewholder.

that is, using a static class, save The reference relationship for each child View in the XML , so that you do not have to parse the XML every time up. As follows: A viewholder written for the code above


Static class Viewholder {     TextView titletextview;      



However, in the getview We can only get three parameters in the method, position , convertview , viewgroup is not getting our custom viewholder convertview get viewholder tag

The following is a complete Viewholder Use exmaple:

    Public View GetView (int position, View Convertview, ViewGroup parent) {        Viewholder holder;        if (Convertview = = null) {            Convertview = minflater.inflate (R.layout.item_view, null);            Holder = new Viewholder ();            Holder.titletextview = (TextView) Convertview.findviewbyid (r.id.text);            Holder.iconimageview = (ImageView) Convertview.findviewbyid (R.id.icon);            Convertview.settag (holder);        } else {            holder = (viewholder) convertview.gettag ();        }        Holder.titleTextView.setText (data[pos].title);        Holder.iconImageView.setImageBitmap (DATA[POS].BITMAP);        return convertview;    }    Static class Viewholder {        TextView titletextview;        ImageView Iconimageview;    }

Tips. Support.v7 in the Recyclerview is the use of this idea to make.

Multiple types of ViewType

When we call method GetView in adapter, if the item view in the entire list has multiple types of layouts, such as:


We continue to use Convertview to populate the data as if it were not possible, because each returned Convertview type is different and cannot be reused.

This is what Android is thinking about when it comes to design. Therefore, the two methods reserved in the adapter.

public int Getitemviewtype (int position);


public int getviewtypecount ();

Only need to re-two methods, set the number of Itemviewtype and judgment method, recycler can selectively give different convertview.

Example:

    @Override public intgetitemviewtype (int position) {if (Data[pos].type = = 0) {return 0;        } else {return 1;    }} @Override public int getviewtypecount () {return 2; } @Override public View getView (int position, view Convertview, ViewGroup arg2) {Titleviewholder titleholder        ;        Infoviewholder Infoholder;        int type = Getitemviewtype (position); if (Convertview = = null) {switch (type) {Case 0:convertview = minflater.inflate (R).                Layout.item_view, NULL);                Titleholder = new Titleviewholder ();                Titleholder.titletextview = (TextView) Convertview.findviewbyid (R.id.text);                Titleholder.iconimageview = (ImageView) Convertview.findviewbyid (R.id.icon);                Convertview.settag (titleholder);            Break            Case 1:convertview = minflater.inflate (r.layout.item_view2, NULL);    Infoholder = new Infoviewholder ();                Infoholder.titletextview = (TextView) Convertview.findviewbyid (R.id.text);                Convertview.settag (Infoholder);            Break }} else {switch (type) {case 0:titleholder = (titleviewholder) convertview                . Gettag ();            Break                Case 1:infoholder = (infoviewholder) convertview.gettag ();            Break            }} switch (type) {case 0:titleholder.titletextview.settext (data[pos].title);        Break            Case 1:infoholder.titletextview.settext (Data[pos].title);            InfoHolder.iconImageView.setImageBitmap (DATA[POS].BITMAP);        Break    } return Convertview;        } static class Titleviewholder {public ImageView iconimageview;    Public TextView Titletextview;  } static class Infoviewholder {TextView titletextview;      ImageView Iconimageview; }


notifydatasetchanged Refresh mechanism

When the data in the ListView changes and we want to refresh the view in the ListView, we typically call notifydatasetchanged to refresh the ListView. Take a look at its source code:


    public void notifychanged () {        synchronized (mobservers) {            //sends a onchanged for            (int i =) to each child view Mobservers.size ()-1; I >= 0; i--) {                mobservers.get (i). onChanged ();}}    }



It was found to be refreshed for every sub-view, of course, if our data variables were understandable. However, under general conditions, we need to update the view not much. Frequent calls to the notifydatasetchanged method are not appropriate for refreshing the entire interface. This will redraw all items displayed on the interface Once, even if only one view has changed.

So, we can write an update method to refresh a view individually

private void Updateview (int itemIndex) {    intvisibleposition = yourlistview.getfirstvisibleposition ();    VIEWV = Yourlistview.getchildat (itemindex-visibleposition);         Viewholder Viewholder = (viewholder) v.gettag ();         if (viewholder!= null) {               ViewHolder.titleTextView.setText ("I updated");}   }


Network picture optimization in adapter

Each item in the ListView has a network image, and when item is more, too many Web requests and too many image stores will be the ListView variable card.


So do the optimization for it:

Using the thread pool for network picture requests, network picture requests are obtained using local cache processing (LRUCache), memory + local file cache. Of course, a weak reference (WeakReference) is required to store the in-memory image in order to prevent memory overflow from being recycled.

Proportionally scales the pictures taken in the network to reduce memory consumption.

When you swipe, you don't need to request a Web image. Because, the network request is generally more time-consuming, an item of the picture, in the request when the recycler replaced, the picture will not correspond to the item.

Tips. The network request of the tool class is more inconvenient to cite examples, but the use of more frequent network Image request Tool class is volley, volley provides a Imageloader tool class and Networkimageview network picture request view




/**
* @author Zhoushengtao (Zhou San)
* @since July 8, 2014 15:08:29
* @weixin stchou_zst

* @blog http://blog.csdn.net/yzzst
*/


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.