Typical optimization methods of ListView in Android: androidlistview

Source: Internet
Author: User

Typical optimization methods of ListView in Android: androidlistview

In Android, ListView should be regarded as one of the most common components in layout, which is also very convenient to use. The following describes some common Optimization Methods for ListView:

First, we provide an Adapter class without any Optimization for Listview. Here we inherit from BaseAdapter, here we use a List set containing 100 strings as the content to be displayed in the ListView project. Each entry is a custom component, which contains only one textview:


Activity:

Package com. alexchen. listviewoptimize; import java. util. arrayList; import java. util. list; import android. app. activity; import android. OS. bundle; import android. view. menu; import android. view. menuItem; import android. view. view; import android. view. viewGroup; import android. widget. baseAdapter; import android. widget. listView; import android. widget. textView; public class MainActivity extends Activity {private ListView lv_demo; private List <String> list; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); lv_demo = (ListView) findViewById (R. id. lv_demo); // list is the set of entry text to be loaded. Here there are a total of 100 list = new ArrayList <String> (); for (int I = 0; I <100; I ++) {list. add ("entry" + I);} lv_demo.setAdapter (new MyAdapter ();} private class MyAdapter extends BaseAdapter {@ Overridepublic int getCount () {return list. size () ;}@ Overridepublic View getView (int position, View convertView, ViewGroup parent) {// there is only one textviewView view = View in listview_item. inflate (MainActivity. this, R. layout. listview_item, null); // use the findviewById method to obtain the TextView TV _item = (TextView) view of the listview_item component. findViewById (R. id. TV _item); TV _item.setText (list. get (position); return view ;}@ Overridepublic Object getItem (int position) {return null ;}@ Overridepublic long getItemId (int position) {return 0 ;}}}

Optimization 1:

It is also the most common optimization. In the getView method of the MyAdapter class, we noticed that every time a View object is required in the above method, a View is re-inflate and returned, view object reuse is not implemented. In fact, for ListView, you only need to retain the maximum number of views that can be displayed, other new views can be reused to use the view that disappears, while the getView method also provides a parameter: convertView, which represents a view object that can be reused, of course, this object may also be empty. When it is empty, it indicates that the view of this entry is created for the first time. Therefore, we need to inflate a view, so here, we use the following method to override the getView method:

@ Overridepublic View getView (int position, View convertView, ViewGroup parent) {View view; // judge the status of convertView to achieve reuse effect if (null = convertView) {// If convertView is empty, the entry is displayed for the first time. You need to create a viewview = View. inflate (MainActivity. this, R. layout. listview_item, null);} else {// otherwise, convertViewview = convertView can be reused;} // there is only one textviewTextView TV _item = (TextView) view in listview_item. findViewById (R. id. TV _item); TV _item.setText (list. get (position); return view ;}


Optimization 2:

The above is the optimization of the reuse of view objects. After the above optimization, we do not need to regenerate every view. Next we will solve the task that needs to be done every time, that is, the component search in the view:

TextView TV _item = (TextView) view. findViewById (R. id. TV _item );

In fact, the findViewById is used to search for the corresponding id in the xml file. It can be imagined that if there are many components, it will be quite troublesome, if we can reuse the components in the view with the reuse of the view, it would be a wonderful thing .. In fact, Google also recommends an optimization method to deal with it, that is, to re-create an internal static class, where the member variables are of the same type as the number of components contained in the view, the view here only contains one TextView, so our static class is as follows:

private static class ViewHolder {private TextView tvHolder;}

So how can we use this viewHolder class to achieve reuse? The basic idea is that when convertView is null, we not only re-inflate a view, but also need to find findviewbyId, but we also need to get a ViewHolder class object, assign the findviewById result to the member variable corresponding to ViewHolder. Finally, the holder object is "bound" to the view object.

When convertView is not null, let's make view = converView and retrieve the holder object corresponding to this view to get the TextView component in this view object, which is the member variable in holder, in this way, we do not need to go to findViewById again when reusing it. We only need to perform several searches at the beginning. The key here is how to bind the view to the holder object. Two methods are required: setTag and getTag:

@ Overridepublic View getView (int position, View convertView, ViewGroup parent) {View view; ViewHolder holder; // judge the convertView status to achieve reuse if (null = convertView) {// If convertView is empty, the entry is displayed for the first time. You need to create a viewview = View. inflate (MainActivity. this, R. layout. listview_item, null); // create a new viewholder object holder = new ViewHolder (); // assign the findviewbyID result to the holder member variable. tvHolder = (TextView) view. findViewById (R. id. TV _item); // bind the holder to the view. setTag (holder);} else {// otherwise, convertViewview = convertView can be reused; holder = (ViewHolder) view can be reused. getTag () ;}// you can directly operate on the member variables in holder. You do not need to use findViewByIdholder every time. tvHolder. setText (list. get (position); return view ;}

After the above practice, you may not feel the optimization effect. According to the Google documentation, the actual optimization effect is about 5 percent.


Optimization 3:

In the above two examples, ListView is the content of the Local List set displayed, and the List length is only 100. We can load the 100 data at a time without any effort; however, in practical applications, we often need to use Listview to display content on the network. For example, we use ListView to display news as an example:

First, if the network condition is good, the mobile phone we use may be able to load all the news data at once, and then display it in ListView, the user may feel better, if the network is not smooth and the user loads all the network data, the list may be 1000 pieces of news, then the user may have to face a blank Activity for several minutes, this is obviously inappropriate.


Second, we know that the runtime memory allocated to each application by the Android virtual machine is fixed. Generally, the performance of a host with poor performance is only 16 MB, which may be 64 MB, let us assume that the total number of news items to be viewed is 10 thousand. Even if the network is good, we can load the news quickly, however, in most cases, memory overflow may also cause application crashes.


In order to solve the two problems above, we need to load them in batches. For example, for the List set of 1000 pieces of news, we need to load 20 pieces at a time and wait until the users flip the pages to the bottom, we will add the following 20 items to the List, and then use the Adapter to refresh the ListView. In this way, you only need to wait for 20 data transmission times at a time, you do not need to wait for several minutes to load the data and display it on the ListView. This can also ease the OOM application crash caused by one loading of many news articles.


In fact, batch loading cannot completely solve the problem, because although we only add 20 pieces of data to the List set at one time in batches, And then refresh the data to the ListView, if there are 0.1 million pieces of data, if we successfully read the final List set, there will still be a massive amount of data, or it may cause OOM, at this time we need to use paging, for example, we divide the 0.1 million pieces of data into 1000 pages, each page contains 100 pieces of data, and each page is loaded with the content in the List set on the previous page, then, batch loading is used for each page, so that the user experience will be better.







Listview optimization methods (original)

Listview A view that shows items in a vertically scrolling list. A list view that displays a vertical scroll subitem. In android development, there are many places where listview is used to display data and form a vertical view. Using listview is a standard adapter mode. The data is displayed as needed by the data --, interface -- xml, and adapter -- adapter. xml describes how the data is displayed, activities. If a custom adapter is used, the getView method will be rewritten to generate the view and data for the item in the getView method. As shown in the figure: Here is an optimization, that is, reusing the view to reduce memory consumption and accelerate item loading. The Optimization in getView is very common. I have summarized the Three optimization methods below. please correct me. First, the convertView is reused, which greatly reduces the memory consumption. If you determine whether convertView is null, You need to generate a view. Then, you can return the View data to the bottom layer and present it to the user. Feature: if the current convertView is null, a view is generated through LayoutInflat. View Code 2: There is a drawback in the above writing, that is, each time you get a View, you need to re-find the findViewById, re-find the control, and then assign values to the control and set the event accordingly. In this case, we are actually doing the same thing, because the geiview actually contains these controls, and the IDs of these controls are the same, that is, as long as the findViewById is in the view, findViewById is not required each time. The second writing method is provided below. There is usually an internal class ViewHolder. This ViewHolder is used to identify some controls in the view to facilitate the setting of Event-related operations, such as onClick, so you don't have to use findViewById every time, reducing the performance consumption. At the same time, convertView is reused, which greatly reduces memory consumption. View Code 3: I personally think this writing method is the most comfortable. The most comfortable way is to look at the Code with a very nice and clear look. Feature. The internal class ViewHolder is used and convertView is reused. The second difference is that a temporary variable "View view = convertView" is used, the view is modified, and the viewView Code is returned. The preceding variable is a centralized method for beginners to learn and summarize. The source Code is as follows: LisViewTest.zip according to the suggestions provided by friends downstairs, we found there are some optimizations. The latest update is as follows: View Code @ Override public View getView (int position, View convertView, ViewGroup parent) {View view = convertView; ViewHolder holder; if (view = null) {view = LayoutInflater. from (context ). inflate (R. layout. section_list_item1, null); holder = new ViewHolder (); holder. TV _name = (TextView) view. findViewById (R. id. contact_contactinfoitem_ TV _name); holder. TV _phone = (TextView) view. findView ...... remaining full text>

How to optimize android listview

1. ViewHolder Tag is indispensable!
2. Avoid using static in BaseAdapter to define global static variables, which has a great impact. static is a keyword in Java. When it is used to modify member variables, this variable belongs to this class, not the instance of this class. Therefore, the lifecycle of a variable modified with static is long.
3. Avoid using threads in the ListView adapter as much as possible, because the main cause of thread Memory leakage is that the thread lifecycle cannot be controlled.
Hope to help you.

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.