A Preliminary Study on ListView

Source: Internet
Author: User

A Preliminary Study on ListView
1. Introduction to ListView

In Android development, ListView is a commonly used control. It is often used to display a dataset in the form of a list and adaptive display based on the length of the data.

ListView usually has two main functions:

(1) Fill the dataset in the layout and display it to the user.

To implement this function, the following three elements are required:

  • View of each row of data (can be understood as a layout file)
  • Fill in the View dataset (which can be understood as an array of the dataset)
  • Connect the Adapter of the dataset to the ListView (it can be understood as the adapter)

To use ListView, you must first understand what an adapter is. The adapter is a bridge between data and AdapterView. It can be used to effectively separate data from AdapterView, making it easier to bind AdapterView to data and making modifications easier.

(2) process user-clicked item events

MListView. setOnItemClickListener (new OnItemClickListener (){...});

Ii. ListView provides many adapters in Android. The following table lists the commonly used adapters.
Adapter type Description
ArrayAdapter <T> It is used to bind an array and supports generic operations.
SimpleAdapter Data used to bind the control defined in XML
SimpleCursorAdatpter Used to bind cursor data (usually database-related operations)
BaseAdapter Common basic adapters
A. Use ArrayAdapter <T>

ArrayAdapter can be used to bind simple ListView data. By default, ArrrayAdapter binds the String value of each object to the pre-defined textview control in layout.

Example:

Layout file: activity_main.xml

 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3     xmlns:tools="http://schemas.android.com/tools" 4     android:layout_width="match_parent" 5     android:layout_height="match_parent" 6     android:paddingBottom="@dimen/activity_vertical_margin" 7     android:paddingLeft="@dimen/activity_horizontal_margin" 8     android:paddingRight="@dimen/activity_horizontal_margin" 9     android:paddingTop="@dimen/activity_vertical_margin"10     tools:context="com.example.ubuntu.listviewtest.MainActivity">11 12     <ListView13         android:id="@+id/lv"14         android:layout_width="match_parent"15         android:layout_height="wrap_content"16         />17 </RelativeLayout>

MainActivity. java Initialization

1 package com. example. ubuntu. listviewtest; 2 3 import android. support. v7.app. appCompatActivity; 4 import android. OS. bundle; 5 import android. widget. arrayAdapter; 6 import android. widget. listView; 7 8 public class MainActivity extends AppCompatActivity {9 10 public ListView mListView; // defines the listView object 11 public String [] strs = {"one", "two ", "three", "four", "five"}; // generate the dataset 12 13 @ Override14 protected void onCreate (Bundle savedInstanceState) {15 super. onCreate (savedInstanceState); 16 setContentView (R. layout. activity_main); 17 18 mListView = (ListView) findViewById (R. id. lv); // initialize listview19 mListView. setAdapter (new ArrayAdapter <String> (this, android. r. layout. simple_list_item_1, strs); // adapted data 20} 21}View Code

Shows the effect:

To sum up the usage steps:

(1) define an array to store the items in the ListView. (Raw data) (2) create an ArrayAdapter object by implementing the ArrayAdapter constructor. (New ArrayAdapter () (3) bind ArrayAdapter through the setAdapter () method of ListView. In step 2, it is necessary to mention that ArrayAdapter has multiple constructor functions. In this example, the most commonly used constructor is implemented. The first parameter is the context, and the second parameter is a layout containing TextView, which is used to fill in the layout resource ID of each row of ListView. The third parameter is the content of ListView. The second parameter can be used to customize a layout, but the layout must have a TextView control.. We usually use the resources provided by Android. In addition to the resources used in this example, there are also the following commonly used resources to implement ListView with RadioButton and CheckBox. (1) specify the resource android. R. layout. simple_list_item_checked to implement the ListView with a selection box. You need to use the setChoiceMode () method to set whether to select multiple or single choice. Otherwise, the selection effect cannot be achieved, as shown in.
1 lv.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_checked, strs));2 lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
(2) specify the resource android. R. layout. simple_list_item_multiple_choice to implement the ListView with CheckBox. Similarly, you need to use the setChoiceMode () method to set single-choice or multiple-choice operations. The implementation code is as follows:
1 lv.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_multiple_choice, strs));2 lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

(3) specify the resource android. R. layout. simple_list_item_single_choice to implement the ListView with RadioButton. Note that a single choice is not specified here. You must use the setChoiceMode () method to specify the multiple-choice or single-choice options for the running effect. The implementation code is as follows:
1 lv.setAdapter(newArrayAdapter<String>(this,android.R.layout.simple_list_item_single_choice,strs));2 lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
As mentioned above, ListView also processes user operations in addition to data filling. You can bind a click listener to the ListView using the following code. After clicking the listener, the number of lines clicked is displayed in the title bar.
1 lv. setOnItemClickListener (new OnItemClickListener () {2 @ Override3 publicvoid onItemClick (AdapterView <?> Parent, View view, int position, long id) {4 // The Row 5 setTitle ("You clicked" + arg2 + "row"); 6} 7} is displayed on the title });
B. Use SimpleAdapterMost of the time, you need to display something other than text in the list, such as slice. At this time, SimpleAdapter can be used. SimpleAdapter is also very simple to use, and its functions are also very powerful. You can use it to customize the content of items in the ListView, such as slice and multi-choice box. Let's look at an example to implement a ListView with an ImageView and TextView for each row. Let's take a look at the running effect ,. First, add a ListView control to the layout file. You also need to define the layout of each row in a ListView, and use RelativeLayout to implement a layout with two lines of words and an image. Item. xml:
 1 <?xmlversion="1.0"encoding="utf-8"?> 2 <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"  3 android:layout_height="fill_parent" android:layout_width="fill_parent">  4  5     <ImageView 6         android:layout_alignParentRight="true"  7         android:layout_width="wrap_content" 8         android:layout_height="wrap_content"  9         android:id="@+id/ItemImage"/> 10     <TextView11         android:id="@+id/ItemTitle" 12         android:layout_height="wrap_content" 13         android:layout_width="fill_parent" 14         android:textSize="20sp"/>15      <TextView16         android:id="@+id/ItemText" 17         android:layout_height="wrap_content" 18         android:layout_width="fill_parent" 19         android:layout_below="@+id/ItemTitle"/> 20 </RelativeLayout>

After configuration, You can bind data to ListView in Java code.

1 public class MyListViewSimple extends Activity {2 private ListView lv; 3/** Called when the activity is first created. * // @ Override 4 public void onCreate (Bundle savedInstanceState) {5 super. onCreate (savedInstanceState); 6 setContentView (R. layout. main); 7 lv = (ListView) findViewById (R. id. lv);/* define a dynamic array */8 ArrayList <HashMap <String, Object> listItem = new ArrayList <HashMap <String, Object> ();/ * Store data in the array */9 for (int I = 0; I <10; I ++) {10 HashMap <String, Object> map = new HashMap <String, object> (); 11 map. put ("ItemImage", R. drawable. icon); // Add the image 12 map. put ("ItemTitle", "row" + I + "); 13 map. put ("ItemText", "this is the" + I + "row"); 14 listItem. add (map); 15} 16 SimpleAdapter mSimpleAdapter = new SimpleAdapter (this, listItem, 17 // data to be bound 18 R. layout. item, 19 // The layout of each row // the data source key in the dynamic array corresponds to 20 new String [] {"in the View that defines the layout. ItemImage "," ItemTitle "," ItemText "}, 21 new int [] {R. id. itemImage, R. id. itemTitle, R. id. itemText}); 22 lv. setAdapter (mSimpleAdapter); // bind the adapter 23 lv to the ListView. setOnItemClickListener (new 24 OnItemClickListener () {25 @ Override26 publicvoid onItemClick (AdapterView <?> Arg0, View arg1, int arg2, 27 long arg3) {28 setTitle ("You clicked" + arg2 + "row "); // set the title bar to display the row 29} 30}); 31} 32}The data of View Code using simpleAdapter is generally a list composed of HashMap. Each section of the list corresponds to each row of ListView. Through the SimpleAdapter constructor, map the data of each key of HashMap to the corresponding control in the layout file. This layout file is generally defined according to your own needs. Sort out the steps for using SimpleAdapter. (1) define the layout implemented by each row of the ListView as needed. Item. xml (2) defines a list composed of HashMap, stores data in the ArrayList <HashMap <String, Object> listItem = new ArrayList <HashMap <String, object >>> (); (3) construct SimpleAdapter Object SimpleAdapter mSimpleAdapter = new SimpleAdapter (4) bind LsitView to SimpleAdapter. Lv. setAdapter (mSimpleAdapter ); C. Use BaseAdapterIn the use of ListView, you sometimes need to add buttons and other controls in it to implement separate operations. That is to say, the ListView does not only display data, but also processes user operations, but controls in it need to gain the user's focus. You can try to use SimpleAdapter to add a button to the ListView entry. You will find that the button can be added but cannot get the focus. The click operation is overwritten by the ListView Item. At this time, the most convenient way is to use the flexible adapter BaseAdapter. To use BaseAdapter, you must write a class to inherit it. Because BaseAdapter is an abstract class, it must inherit its methods. The flexibility of BaseAdapter lies in its many methods to be rewritten. Let's take a look at which methods are available, as shown in the method implemented by the SpeechListAdapter inherited from BaseAdapter. The most important one is the getView () method. What are the functions of these methods? We can solve this problem by analyzing the principle of ListView. When the system starts to draw the ListView, The getCount () method is called first. The returned value is the length of the ListView. Then the system calls the getView () method and draws each row of the ListView one by one based on the length. That is to say, if getCount () returns 1, only one row is displayed. GetItem () and getItemId () are called when data in the Adapter needs to be processed and obtained. How to Use getView? If there are 10000 rows of data, it will be drawn 10000 times? This will definitely consume a lot of resources and cause the ListView to slide very slowly. What should we do? An example is provided to illustrate how to optimize the display of ListView when using BaseAdapter. In this example, the ImageView in the previous section is replaced with a Button and the Button click event is processed. The ListView display is optimized. 1/* 2 * create a class that inherits the BaseAdapter and bind the view to the data. 3 */4 private class MyAdapter extends BaseAdapter {5 private LayoutInflater mInflater; // obtain a LayoutInfalter object used to import layout 6 7/* constructor */8 public MyAdapter (Context context) {9 this. mInflater = LayoutInflater. from (context); 10} 11 @ Override12 publicint getCount () {13 return getDate (). size (); // returns the length of the array 14} 15 @ Override16 public Object getItem (int position) {17 return null; 18} 19 @ Override20 public long getItemId (int position) {21 return 0; 22} 23/* describes this method in detail */24 @ Override25 public View getView (finalint position, View convertView, ViewGroup parent) {26 ViewHolder holder; 27 // observe convertView scrolling with ListView 28 Log. v ("MyListViewBase", "getView" + position + "" + convertView); 29 if (convertView = null) {30 convertView = mInflater. inflate (R. layout. item, null); 31 holder = new ViewHolder (); 32/* Get the object of each control */33 holder. title = (TextView) convertView. findViewById (R. id. itemTitle); 34 holder. text = (TextView) convertView. findViewById (R. id. itemText); 35 holder. bt = (Button) convertView. findViewById (R. id. itemButton); 36 convertView. setTag (holder); // bind ViewHolder object 37} 38 else {39 holder = (ViewHolder) convertView. getTag (); // retrieve the ViewHolder object 40/* set the content displayed in TextView, that is, the data we store in the dynamic array */41 holder. title. setText (getDate (). get (position ). get ("ItemTitle "). toString (); 42 holder. text. setText (getDate (). get (position ). get ("ItemText "). toString (); 43} 44/* Add a click event for the Button */45 holder. bt. setOnClickListener (new OnClickListener () {46 @ Override47 publicvoid onClick (View v) {48 Log. v ("MyListViewBase", "you clicked the Button" + position); // print the Button's click information 49} 50}); 51 return convertView; 52} 53 54} 55/* storage control */56 public final class ViewHolder {57 public TextView title; 58 public TextView text; 59 public Button bt; 60} 61}View Code

Running effect. Note that the Button will snatch the focus of the ListView, and the Button must be set to no focus. The setting is very simple. You only need to add a line under the xml Button Tag: android: focusable = "false. Observe the information output after clicking LogCat, as shown in.

The getView () method in the Code is not easy to understand. In fact, you can directly import the layout and set the display content of the control without the so-called convertView and ViewHolder. However, this means that the number of rows of data to be drawn is obviously not desirable. An optimization method is used here. In the code, add a line of log output convertView content to the getView () method. Scroll down the ListView, as shown in Figure 4-38. It can be seen that when the Activity is started to display the first screen of ListView, convertView is NULL. When you scroll down the ListView, the preceding entries become invisible, and new entries appear below. At this time, convertView is no longer empty, but creates a series of convertView values. When the screen is rolled down, it is found that 11th rows of containers are used to hold 22nd rows, and 12th rows of containers are used to hold 23rd rows. That is to say, convertView is equivalent to a cache and starts to 0. When an entry becomes invisible, it caches its data and the subsequent entries only need to update the data, this greatly saves the cost of system data. You can continue optimization. Although the previously drawn view is reused, to obtain the control, you must use the findViewById method in the control container. If the container is very complex, it will obviously increase the overhead of system resources. In the above example, the concept of Tag is introduced. Maybe not the best way, but it does make ListView smoother. In the Code, when convertView is empty, use the setTag () method to bind a ViewHolder object for each View to store the control. When convertView is not empty and you reuse the created view, use the getTag () method to obtain the bound ViewHolder object. This avoids layer-by-layer query of the findViewById control, instead, you can quickly locate the control.To sum up, this section describes how to bind ListView data with BaseAdapter. Because BaseAdapter is flexible, it is more difficult to use than other controls. At the same time, the problem of ListView optimization is also worth studying. A smooth ListView will bring a better user experience. Iii. ListView Summary

When using ListView, pay attention to the following four points:

1. layout file: add the ListView control to the layout file.

2. Data source: (data downloaded on the network side; custom data; data read from the database)-array related to the Dataset

3. Adapter: ArrayAdapter <T>; SimpleAdapter; SimpleCursorAdatpter; BaseAdapter called as needed. We recommend that you extend the complex itemView layout file by inheriting the BaseAdapter.

4. Performance Optimization: when using the ListView layout file, we recommend that you set the android: layout_height height attribute to "match_parent" instead of "wrap_content ".

If it is set to wrap_content, each time the ListView is drawn, the height of the entire listview is measured again, resulting in repeated calls of the bindview function.

If the dataset is large, the display of the entire listview will be slow and the user experience is poor. In the future, a blog will be devoted to performance tuning to illustrate this point.

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.