ListView是我們在Android應用開發中常用的組件,它通過列表的形式展示數據,具有很強的可擴展性,通常使用還會給每一項綁定一個點擊時間,用於處理相應的請求,ListView在電商的商品列表中是必不可少的,下面我們介紹幾種常用的使用方法。
列表的顯示需要三個元素:
1.ListVeiw 用來展示列表的View。
2.適配器 用來把數據映射到ListView上的中介。
3.數據 具體的將被映射的字符串,圖片,或者基本組件。
android中我們常用的有3中不同的適配器,分別是:
1.ArrayAdapter 使用最為簡單,以數據集合為基礎,只顯示一行文本。
2.SimpleAdapter 具有很好的擴種行,可以自定義出各種各樣的布局。
3.SimpleCursorAdapter 可以方便的把數據庫的內容通過列表的形式展現出來
另外,我們通常自己寫一個繼承自BaseAdapter(基礎適配器)的適配器,用於將設計思路更加的符合規范,數據與視圖分離開來,像MVC一樣。
下面我們逐一介紹着幾種方式:
(一)、ArrayAdapter適配器
ArrayAdapter可以實現簡單的數據與ListView的綁定,我們逐步實現ListView。
1、在布局文件中加入一個ListView組件
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <ListView
- android:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、在Activity中分別獲取列表、數據、適配器。
- public class MainActivity extends Activity {
- private ListView myListView;//列表
- private List<String> itemList;//數據
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initData();
- myListView = (ListView) findViewById(R.id.listView);
- //ArrayAdapter中有三個參數
- //Context context 指定現在的上下文
- //int textViewResourceId 指定一個包含textview的布局文件,顯示每行的信息
- //List<String> objects 在listview上顯示的數據信息
- ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(MainActivity.this,
- android.R.layout.simple_list_item_1, itemList);//適配器
- }
- public void initData() {
- itemList = new ArrayList<String>();
- for (int i = 0; i < 20; i++) {
- itemList.add("測試數據" + i);
- }
- }
- }
3、看一下實現的效果
可以看到,listView中的每一項都只顯示了一行信息,這種適配器,在需要顯示每項內容只有一個時比較常用,一般我們的listView中每項都有較多的內容,所以還需要更加充實的適配器。
(二)、SimpleAdapter適配器
這是一個簡單的適配器,可以將靜態數據映射到XML文件中定義好的視圖。你可以指定由Map組成的List(比如ArrayList)類型的數據。在ArrayList中的每個條目對應List中的一行。Maps包含每一行的數據。你可以指定一個XML布局以指定每一行的視圖,根據Map中的數據映射關鍵字到指定的視圖。綁定數據到視圖分兩個階段,首先,如果設置了SimpleAdapter.ViewBinder,那么這個設置的ViewBinder的setViewValue(android.view.View, Object, String)將被調用。如果setViewValue的返回值是true,則表示綁定已經完成,將不再調用系統默認的綁定實現。如果返回值為false,視圖將按以下順序綁定數據:
• 如果View實現了Checkable(例如CheckBox),期望綁定值是一個布爾類型。
• TextView.期望綁定值是一個字符串類型,通過調用setViewText(TextView, String)綁定。
• ImageView,期望綁定值是一個資源id或者一個字符串,通過調用setViewImage(ImageView, int) 或 setViewImage(ImageView, String)綁定數據。
• 如果View實現了Checkable(例如CheckBox),期望綁定值是一個布爾類型。
• TextView.期望綁定值是一個字符串類型,通過調用setViewText(TextView, String)綁定。
• ImageView,期望綁定值是一個資源id或者一個字符串,通過調用setViewImage(ImageView, int) 或 setViewImage(ImageView, String)綁定數據。
如果沒有一個合適的綁定發生將會拋出IllegalStateException。
1、在布局文件中加入一個ListView組件
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <ListView
- android:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、自定義一個ListView每一項的布局,里面放一個圖片和兩個文本。
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/white" >
- <ImageView
- android:id="@+id/item_image"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:padding="5dp"
- android:scaleType="fitXY"
- android:src="@drawable/bank_boc" />
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@id/item_image"
- android:layout_marginLeft="10dp"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/item_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="標題"
- android:textColor="#000"
- android:textSize="25sp" />
- <TextView
- android:id="@+id/item_data"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="內容"
- android:textColor="#222"
- android:textSize="20sp" />
- </LinearLayout>
- </RelativeLayout>
效果如下:
3、在Activity中使用SimpleAdapter
- public class SimpleAdapterListActivity extends Activity {
- private ListView myListView;
- private List<HashMap<String, Object>> data;
- private final String TITLE = "title";
- private final String IMAGE = "image";
- private final String DATA = "data";
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- myListView = (ListView) findViewById(R.id.listView);
- initData();
- // 參數:
- // context SimpleAdapter關聯的View的運行環境
- // data 一個Map組成的List。在列表中的每個條目對應列表中的一行,每一個map中應該包含所有在from參數中指定的鍵
- // resource 一個定義列表項的布局文件的資源ID。布局文件將至少應包含那些在to中定義了的ID
- // from 一個將被添加到Map映射上的鍵名
- // to 將綁定數據的視圖的ID,跟from參數對應,這些應該全是TextView
- SimpleAdapter simAdapter = new SimpleAdapter(
- SimpleAdapterListActivity.this, data, R.layout.item_listsimple,
- new String[] { TITLE, DATA, IMAGE }, new int[] {
- R.id.item_title, R.id.item_data, R.id.item_image });
- myListView.setAdapter(simAdapter);
- }
- public void initData() {
- data = new ArrayList<HashMap<String, Object>>();
- for (int i = 0; i < 20; i++) {
- HashMap<String, Object> mapItem = new HashMap<String, Object>();
- mapItem.put(TITLE, "標題" + i);
- mapItem.put(DATA, "介紹" + i);
- switch (i % 3) {
- case 0:
- mapItem.put(IMAGE, R.drawable.bank_boc);
- break;
- case 1:
- mapItem.put(IMAGE, R.drawable.bank_fjnx);
- break;
- case 2:
- mapItem.put(IMAGE, R.drawable.bank_visa);
- break;
- default:
- break;
- }
- data.add(mapItem);
- }
- }
- }
4、看一下效果
(三)、SimpleCursorAdapter適配器
SimpleCursorAdapter是android中專門為連接數據庫與視圖產生的,我們下面測試下使用SimpleCursorAdapter取到手機中的聯系人。
1、在布局文件中加入一個ListView組件
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <ListView
- android:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、在Activity中添加相應代碼
- public class SimpleCursorActivity extends Activity {
- private ListView myListView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- myListView = (ListView)findViewById(R.id.listView);
- @SuppressWarnings("deprecation")
- Cursor cursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
- startManagingCursor(cursor);
- ListAdapter listAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_1, cursor, new String[]{People.NAME}, new int[]{android.R.id.text1});
- myListView.setAdapter(listAdapter);
- }
- }
3、讀取聯系人要用到權限,在AndroidMenifest.xml中添加權限
- <uses-permission android:name="android.permission.READ_CONTACTS"/>
4、在模擬器中加入一條聯系人數據,可以看到運行后效果
(四)、自定義適配器
在我們實際的應用中,通常使用自定義適配器,自定義適配器繼承BaseAdapter,下面我們使用自定義的Adapter來實現(二)中介紹的SimpleAdapter的效果,
1、Activity的界面文件
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- <ListView
- android:id="@+id/listView"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
- </ListView>
- </RelativeLayout>
2、ListView每一項的布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@android:color/white" >
- <ImageView
- android:id="@+id/item_image"
- android:layout_width="80dp"
- android:layout_height="80dp"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:padding="5dp"
- android:scaleType="fitXY"
- android:src="@drawable/bank_boc" />
- <LinearLayout
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:layout_toRightOf="@id/item_image"
- android:layout_marginLeft="10dp"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/item_title"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="標題"
- android:textColor="#000"
- android:textSize="25sp" />
- <TextView
- android:id="@+id/item_data"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="內容"
- android:textColor="#222"
- android:textSize="20sp" />
- </LinearLayout>
- </RelativeLayout>
3、定義一個java類,用來存放在listItem中的每項數據
- public class ListItemModel {
- private String title;
- private String data;
- private int rid;
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- public String getData() {
- return data;
- }
- public void setData(String data) {
- this.data = data;
- }
- public int getRid() {
- return rid;
- }
- public void setRid(int rid) {
- this.rid = rid;
- }
- }
4、自定義適配器
- public class MyListAdapter extends BaseAdapter {
- private List<ListItemModel> listItems;
- private LayoutInflater layoutInflater;
- public MyListAdapter(Context context) {
- layoutInflater = LayoutInflater.from(context);
- }
- public List<ListItemModel> getListItems() {
- return listItems;
- }
- public void setListItems(List<ListItemModel> listItems) {
- this.listItems = listItems;
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return listItems.size();
- }
- @Override
- public Object getItem(int position) {
- // TODO Auto-generated method stub
- return null;
- }
- @Override
- public long getItemId(int position) {
- // TODO Auto-generated method stub
- return 0;
- }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- // TODO Auto-generated method stub
- ListItemView myListItemView;
- if (convertView == null) {
- myListItemView = new ListItemView();
- convertView = layoutInflater
- .inflate(R.layout.item_listsimple, null);
- myListItemView.setTv_title((TextView) convertView
- .findViewById(R.id.item_title));
- myListItemView.setTv_data((TextView) convertView
- .findViewById(R.id.item_data));
- myListItemView.setIv_image((ImageView) convertView
- .findViewById(R.id.item_image));
- convertView.setTag(myListItemView);
- } else {
- myListItemView = (ListItemView) convertView.getTag();
- }
- myListItemView.getTv_title()
- .setText(listItems.get(position).getTitle());
- myListItemView.getTv_data().setText(listItems.get(position).getData());
- myListItemView.getIv_image().setImageResource(
- listItems.get(position).getRid());
- return convertView;
- }
- class ListItemView {
- private TextView tv_title;
- private TextView tv_data;
- private ImageView iv_image;
- public TextView getTv_title() {
- return tv_title;
- }
- public void setTv_title(TextView tv_title) {
- this.tv_title = tv_title;
- }
- public TextView getTv_data() {
- return tv_data;
- }
- public void setTv_data(TextView tv_data) {
- this.tv_data = tv_data;
- }
- public ImageView getIv_image() {
- return iv_image;
- }
- public void setIv_image(ImageView iv_image) {
- this.iv_image = iv_image;
- }
- }
- }
5、Activity中添加數據和適配器,並與ListView綁定
- public class MyAdapterActivity extends Activity {
- private ListView listView;
- private String[] str_titles = { "自定義標題1", "自定義標題2", "自定義標題3", "自定義標題4",
- "自定義標題5", "自定義標題6", "自定義標題7", "自定義標題8", "自定義標題9" };
- private String[] str_datas = { "我的內容1", "我的內容2", "我的內容3", "我的內容4", "我的內容5",
- "我的內容6", "我的內容7", "我的內容8", "我的內容9" };
- private int[] rids = { R.drawable.bank_boc, R.drawable.bank_fjnx,
- R.drawable.bank_visa, R.drawable.bank_boc, R.drawable.bank_fjnx,
- R.drawable.bank_visa, R.drawable.bank_boc, R.drawable.bank_fjnx,
- R.drawable.bank_visa };
- private List<ListItemModel> myListItems;
- private MyListAdapter adapter;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- listView = (ListView) findViewById(R.id.listView);
- myListItems = new ArrayList<ListItemModel>();
- initData();
- adapter = new MyListAdapter(MyAdapterActivity.this);
- adapter.setListItems(myListItems);
- listView.setAdapter(adapter);
- listView.setOnItemClickListener(new OnItemClickListener() {
- @Override
- public void onItemClick(AdapterView<?> parent, View view,
- int position, long id) {
- // TODO Auto-generated method stub
- Toast.makeText(MyAdapterActivity.this, "點擊了" + position, 1000)
- .show();
- }
- });
- }
- public void initData() {
- for (int i = 0; i < str_titles.length; i++) {
- ListItemModel lm = new ListItemModel();
- lm.setTitle(str_titles[i]);
- lm.setData(str_datas[i]);
- lm.setRid(rids[i]);
- myListItems.add(lm);
- }
- }
- }
6、看一下實現的效果
