Android中ListView的初步认识(二)

        在Android中使用一个控件,一般要有两样东西,一是样式,二是数据。

        在第一篇中,我们的ListView使用了Android提供的默认样式android.R.layout.simple_list_item_1,这个样式其实就是每个item是一个TextView。数据我们是声明了一个List并赋值的。最后,我们用了这样一句代码实现了把这些绑定到ListView中:

ArrayAdapter<String> adpater = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,data);

概述         

         所以这篇主要的学习内容是在ListView中使用的Adpter。

         说起Adapter,我第一个想到的就是适配器模式,虽然设计模式学得不怎么样,但是这个词还是记着的。让我们看一下在API中对Adapter的说明:

An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.(Adapter对象在AdapterView和数据之间扮演者桥梁的角色,Adapter提供了通向数据项的途径。Adapter还负责为数据集中的每一个数据项生成view)

Android中ListView的初步认识(二)


Adapter的子类:

Android中ListView的初步认识(二)

以上两图来自(http://www.cnblogs.com/devinzhang/archive/2012/01/20/2328334.html)


     Adapter有很多子类,ListActivity中用到的是ListAdpter,ListActivity提供setListAdapter方法来出入使用的Adpter

    public void setListAdapter(ListAdapter adapter) {
        synchronized (this) {
            ensureList();
            mAdapter = adapter;
            mList.setAdapter(adapter);
        }
    }

     ListAdpter在API中的描述如下:

Extended Adapter that is the bridge between a ListView and the data that backs the list. Frequently that data comes from a Cursor, but that is not required. The ListView can display any data provided that it is wrapped in a ListAdapter.(ListAdapter继承了Adapter,作为ListView和数据集之间的桥梁。通常,数据来源于Cursor,但是不是必须的。ListView可以显示任何被ListAdapter所包装的数据)

      但是ListAdpter是个接口,我们用的时候不会直接用它,而是用到实现这个接口的ArrayAdapter<T>,SimpleAdapter,SimpleCursorAdapter。

接下来,我是介绍这几种adapter的用法:


ArrayAdapter

       ArrayAdapter是安卓提供的一个支持泛型的adapter,这个有点是比较方便,而且有默认定义好的几种样式供选择。

       ArrayAdapter提供了几种构造方法:

Public Constructors
ArrayAdapter(Context context, int resource)
Constructor
ArrayAdapter(Context context, int resource, int textViewResourceId)
Constructor
ArrayAdapter(Context context, int resource, T[] objects)
Constructor
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
Constructor
ArrayAdapter(Context context, int resource, List<T> objects)
Constructor
ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects)
Constructor
Parameters
context The current context.
resource The resource ID for a layout file containing a layout to use when instantiating views.(Item对应的布局文件的id)
textViewResourceId The id of the TextView within the layout resource to be populated(TextView对应的布局文件的id)
objects The objects to represent in the ListView.(要显示的数据集)

安卓为我们提供了几种查用的Item的布局文件:比如我在第一篇的例子中用到的android.R.layout.simple_list_item_1,这个布局文件中只有一个TextView

我们可以看一下它的源码:

<?xml version="1.0" encoding="utf-8"?>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>
       我们也可以使用其它Android提供的配置文件

       需要注意的是,因为我在第一篇的例子中使用的android.R.layout.simple_list_item_1这个样式,在这个样式中只有一个TextView,所以我可以用只有三个参数的构造函数

        ArrayAdapter<String> adpter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,data);

        如果在配置文件中有不止一个view,则需要指定数据放到哪个view中,例如如果使用simple_list_item_single_choice在这个配置文件中有两个TextView则需要四个参数的构造函数

           ArrayAdapter<String> adpter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice,android.R.id.text1,data);

        这两个的运行结果如下图

Android中ListView的初步认识(二)Android中ListView的初步认识(二)




SimpleAdapter

         相对于ArrayAdapter,SimpleAdapter提供了更加灵活的构建ListView的方式。

我们看一下它的构造函数:

Public Constructors
SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
Constructor

Parameters
context The context where the View associated with this SimpleAdapter is running
data A List of Maps. Each entry in the List corresponds to one row in the list. The Maps contain the data for each row,
and should include all the entries specified in "from"
resource Resource identifier of a view layout that defines the views for this list item. The layout file should include at least those named views defined in "to"
from A list of column names that will be added to the Map associated with each item.
to The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values of the first N columns in the from parameter.
其中:
第二个参数,是我们要显示的数据集。List中的每一个Item和ListView中的Item对应。Map中的数据和Item中的列对应。注意Map中的键应当与from]参数一致.
第三个参数,是定义Item样式的配置文件。
第四个参数,是一个数组,要列举出我们要显示的数据在map中的键。
第五个参数,也是一个数组,要列举出我们要现实数据的Item中的view的id,to中的顺序和from中的顺序对应。

下面我看看个小例子:
item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >    
    <ImageView 
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
    />   
    <TextView 
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:layout_gravity="center_vertical"
    />
</LinearLayout>

Activity:
package com.example.listview4;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.os.Bundle;
import android.widget.SimpleAdapter;
import android.app.ListActivity;

public class MainActivity extends ListActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.item, new String[] {"image","text"}, new int[] {R.id.image,R.id.text});
		setListAdapter(adapter);
	}

	private List<Map<String,Object>> getData(){
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("image", R.drawable.ic_launcher);
		map.put("text", "测试1");
		list.add(map);
		
		Map<String,Object> map1 = new HashMap<String,Object>();
		map1.put("image", R.drawable.ic_launcher);
		map1.put("text", "测试2");
		list.add(map1);
		
		Map<String,Object> map2 = new HashMap<String,Object>();
		map2.put("image", R.drawable.ic_launcher);
		map2.put("text", "测试3");
		list.add(map2);
		
		return list;
	}

}

下面是运行结果:

Android中ListView的初步认识(二)



SimpleCursorAdapter

SimpleCursorAdapter提供了将数据库中的数据绑定到ListView中的方法。
先看一下构造方法:
Public Constructors
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
This constructor was deprecated in API level 11. This option is discouraged, as it results in Cursor queries being performed on the application‘s UI thread and thus can cause poor responsiveness or even Application Not Responding errors. As an alternative, use LoaderManager with a CursorLoader.
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags)
Standard constructor.
Parameters
context The context where the ListView associated with this SimpleListItemFactory is running
layout resource identifier of a layout file that defines the views for this list item. The layout file should include at least those named views defined in "to"
c The database cursor. Can be null if the cursor is not available yet.
from A list of column names representing the data to bind to the UI. Can be null if the cursor is not available yet.
to The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values
of the first N columns in the from parameter. Can be null if the cursor is not available yet.
flags Flags used to determine the behavior of the adapter, as per CursorAdapter(Context, Cursor, int).

参数和前面的大同小异,就不介绍了

下面这段代码是参考API中提供的例子写的,但是代码中获取联系人信息的方式在目前的API中已经不被推荐使用,所以仅供学习参考

package com.example.listview5;

import android.app.ListActivity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.widget.ListAdapter;
import android.widget.SimpleCursorAdapter;

@SuppressWarnings("deprecation")
public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        // Query for all people contacts using the Contacts.People convenience class.
        // Put a managed wrapper around the retrieved cursor so we don‘t have to worry about
        // requerying or closing it as the activity changes state.
        Cursor mCursor = this.getContentResolver().query(People.CONTENT_URI, null, null, null, People.TIMES_CONTACTED);
        startManagingCursor(mCursor);

        // Now create a new list adapter bound to the cursor.
        // SimpleListAdapter is designed for binding to a Cursor.
        ListAdapter adapter = new SimpleCursorAdapter(
                this, // Context.
                android.R.layout.two_line_list_item,  
                mCursor,                                              
                new String[] {People.NAME, People.TIMES_CONTACTED},          
                new int[] {android.R.id.text1, android.R.id.text2});  

        // Bind to our new adapter.
        setListAdapter(adapter);
    }
}


其实可以看到SimpleCursorAdapter的用法和SimpleAdapter的用法还是比较类似的,只不过二者的数据源,是一个从数据库中取数,另一个是List。

Android中ListView的初步认识(二),布布扣,bubuko.com

Android中ListView的初步认识(二)

上一篇:Android更新UI的几种方式


下一篇:【综合】JAVA、android中常用的一些jar包的作用,您知道多少?