ListView及ListAdapter詳解

ListView及ListAdapter詳解

一、AdapterView

1. 簡介

An AdapterView is a view whose children are determined by an Adapter.

簡單地說就是其子視圖是由適配器決定的視圖組件

2. 子類

  • ListView
  • GridView
  • Spinner
  • Gallery

3. 常用方法

//功能:獲取list中指定位置item
getItemAtPosition(int position) 
//功能:獲取list中指定位置item 的id
getItemIdAtPosition(int position) 
//功能:Sets the adapter that provides the data and the views to represent the data in this widget.
//翻譯:設置提供數據和顯示數據的視圖的適配器
setAdapter(T adapter) 
//功能:Sets the view to show if the adapter is empty
//翻譯:設置當適配器沒數據時的視圖
setEmptyView(View emptyView) 
//功能:獲取選中的item
getSelectedItem()  
//功能:獲取選中的item的id
long getSelectedItemId()  
//功能:獲取選中的item在數據集中的位置 
int getSelectedItemPosition() 
//功能:Call the OnItemClickListener, if it is defined.
//翻譯:調用列表項點擊事件,如果定義了的話
performItemClick(View view, int position, long id) 
//功能:設置當前選中的item
setSelection(int position) 
//功能:Register a callback to be invoked when this view is clicked.
//翻譯:給視圖設置點擊事件
setOnClickListener(View.OnClickListener l) 
//功能:Register a callback to be invoked when an item in this AdapterView has been clicked.
//翻譯:給適配器視圖中的一項設置點擊事件
setOnItemClickListener(AdapterView.OnItemClickListener listener) 
//功能:Register a callback to be invoked when an item in this AdapterView has been clicked and held
//翻譯:給適配器視圖中的一項設置長按事件
setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener) 
//功能:Register a callback to be invoked when an item in this AdapterView has been selected.
//翻譯:給適配器視圖中的一項設置選中事件
setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) 

二、ListView

1. 簡介

繼承關係

這裏寫圖片描述

以列表滾動形式顯示數據內容,數據內容來自ListAdapter,根據數據長度適應屏幕顯示

2. XML屬性

Attribute Name Description
android:divider Drawable or color to draw between list items. (列表項的分隔線)
android:dividerHeight Height of the divider. (分隔線的高度)
android:entries Reference to an array resource that will populate the ListView. (關聯的數組資源)
android:footerDividersEnabled When set to false, the ListView will not draw the divider before each footer view. (是否要在底部視圖下方也添加分隔線)
android:headerDividersEnabled When set to false, the ListView will not draw the divider after each header view. (是否要在頭部視圖下方也添加分隔線)

3. 方法

/**
*功能:Sets the data behind this ListView.(設置ListView的適配器)
*參數adapter:一個ListAdapter,提供支持listview背後的數據併產生列表項視圖
*/
setAdapter(ListAdapter adapter);
/**
*功能:Add a fixed view to appear at the bottom of the list.(添加底部視圖)
*參數v:要添加的視圖
*/
 addFooterView(View v) ;
/**
*功能:Add a fixed view to appear at the bottom of the list.(添加底部視圖)
*參數v:要添加的視圖
*參數data: Data to associate with this view (跟視圖關聯的數據)有什麼用?關聯的數據可以通過getCount方法獲取
*參數isSelectable :true if the footer view can be selected(視圖是否能被選)
*/
addFooterView(View v, Object data, boolean isSelectable) ;
/**
*功能:Add a fixed view to appear at the bottom of the list.(添加頭部視圖)
*參數v:要添加的視圖
*/
addHeaderView(View v) ;
/**
*功能:Add a fixed view to appear at the bottom of the list.(添加頭部部視圖)
*參數v:要添加的視圖
*參數data: Data to associate with this view (跟視圖關聯的數據)有什麼用?關聯的數據可以通過getCount方法獲取
*參數isSelectable :true if the footer view can be selected(視圖是否能被選)
*/
addHeaderView(View v, Object data, boolean isSelectable) ;

三、Adapter接口

1. 簡介

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.

就是說,適配器對象就是適配器視圖和背後的數據的橋樑。適配器提供數據項的接口,也負責給每個數據項設置視圖。

2. 方法

/**
*功能:How many items are in the data set represented by this Adapter.(獲取條目數)
*點擊事件會觸發getCount();
*在新建view之前和之後會調用幾次getCount()
*條目數包括頭部視圖和底部視圖
*/
getCount();
/**
*功能:Get a View that displays the data at the specified position in the data set.(決定每個列表項的數據和視圖顯示)
*參數position: The position of the item within the adapter's data set of the item whose view we want.
*參數convertView: The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).
*參數parent : The parent that this view will eventually be attached to 
*/
getView(int position, View convertView, ViewGroup parent);
//Get the data item associated with the specified position in the data set. 
getItem(int position) 
//Get the row id associated with the specified position in the list. 
getItemId(int position) 
//true if this adapter doesn't contain any data. This is used to determine whether the empty view should be displayed. A typical implementation will return getCount() == 0 but since getCount() includes the headers and footers, specialized adapters might want a different behavior.
isEmpty()

四、ListAdapter接口

1. 簡介

ListView和數據之間的橋樑,通常數據來源於一個Cursor(遊標),ListView顯示包裝在ListAdapter中的數據。其實現類如下

這裏寫圖片描述

2. 實現類

2.1 BaseAdapter

  1. 簡介

    是一個抽象類,需要重寫View getView(int position, View convertView, ViewGroup parent)int getCount()long getItemId(int position)Object getItem(int position)四個方法,可以做複雜的佈局。

  2. 理解
    調用getView方法返回的是一個列表項視圖,可以是ViewGroup,也可以是View。而ConvertView就是是被指向界面顯示的第一個View的上一個View ,即剛剛被滑出界面的View;這個ConvertView的類型要跟getView返回值保持一致,否則會拋出類型轉換異常;通過複用CovertView,達到優化ListView性能的目的。怎麼複用呢?很簡單,只要就行ConvertView的非空判斷,然後將其賦值給我們自定義的列表項視圖,爲空的話才創建自定義的列表項視圖。

  3. 實例

    /*
    * MainActivity.java中的核心代碼
    * lv爲一個ListView
    * list爲一個ArrayList<Integer>,存放圖片的資源id
    */
    lv.setAdapter(new BaseAdapter() {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v = null;
                if (convertView != null) {
                    v = convertView;
                } else {
                    v = LayoutInflater.from(getApplicationContext()).inflate(
                            R.layout.listview_base, null);
                }
                ImageView img = (ImageView) v.findViewById(R.id.imgBase);
                img.setImageResource(list.get(position));
                return v;
            }
            @Override
            public long getItemId(int position) {
                return position;
            }
            @Override
            public Object getItem(int position) {
                return list.get(position);
            }
            @Override
            public int getCount() {
                return list.size();
            }
        });
    <!--這是listview_base.xml-->  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ImageView
        android:id="@+id/imgArray"
        android:layout_width="match_parent"
        android:layout_height="200dp" >
    </ImageView>
    </LinearLayout>

2.2 ArrayAdapter

  1. 簡介
    是BaseAdapter的子類,是具體類。默認的資源ID指向單個的TextView,當然你可以用其他構造方法,傳入一個更大的佈局,這樣你就可以在一個指向一個更大的佈局中的TextView。或者你想要的是指向ImageView,而不是TextView,這時候你就不得不重寫getView方法了

  2. 構造方法

    這裏寫圖片描述

    參數說明

    • context 上下文
    • resource 包含textView的佈局文件id
    • textViewResourceId textView的id
    • objects 數據集,數組或List集合
  3. 實例

    /*
    * MainActivity.java中的核心代碼
    * lv爲一個ListView
    * list爲一個ArrayList<Integer>,存放圖片的資源id
    */
    lv.setAdapter(new ArrayAdapter<Integer>(MainActivity.this,
                R.layout.listview_array, list) {
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view=null;
                if (convertView != null) {
                    view = convertView;
                } else {
                    view = LayoutInflater.from(getContext()).inflate(R.layout.listview_array, null);
                }
                ImageView imgArray = (ImageView) view.findViewById(
                        R.id.imgArray);
                imgArray.setImageResource(list.get(position));
                return view;
            }
        });
    <!--這是listview_array.xml-->
    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/imgArray"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:scaleType="centerInside" >
    </ImageView>
    //問題:不知道爲什麼xml中寬高設置並不生效?
    //解答:ImageView外圍再包裹一個Layout就可以了。

2.3 SimpleAdapter

  1. 簡介
    是BaseAdapter的子類,是具體類。不想自定義適配器,又要做複雜佈局時用。可以處理一般的組件與數據的綁定。

  2. 構造方法

    /**
    * 參數context:上下文對象
    * 參數data:用於綁定到視圖的列表項爲map的list
    * 參數resource:包裹視圖的資源文件id
    * 參數from:map中要連接到視圖的字段名(key)數組
    * 參數to:與from對應的視圖組件的id數組
    */
    SimpleAdapter(Context context, List<? extends Map<String,?>> data, int resource, String[] from, int[] to) 
    1. 實例
    /*
    * MainActivity.java中的核心代碼
    * lv爲一個ListView
    * list爲一個ArrayList<Integer>,存放圖片的資源id
    */
    List<LinkedHashMap<String, Object>> data = new ArrayList<LinkedHashMap<String,Object>>();
        for (Integer i : list) {
            LinkedHashMap<String, Object> map =  new LinkedHashMap<String, Object>();
            map.put("img", i);
            data.add(map);
        }
        lv.setAdapter(new SimpleAdapter(this, data, R.layout.listview_simple, new String[]{"img"}, new int[]{R.id.imgSimple}));
    <!--這是listview_simple.xml-->        
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <ImageView
        android:id="@+id/imgSimple"
        android:layout_width="match_parent"
        android:layout_height="200dp" >
    </ImageView>
    </LinearLayout>

2.4 SimpleCursorAdapter

  1. 簡介

    An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. You can specify which columns you want, which views you want to display the columns, and the XML file that defines the appearance of these views.

    簡單地說,就是一個類似於SimpleAdapter的適配器,只是它的數據源是一個cursor對象。

  2. 構造方法

    /**
    * 參數context:上下文對象
    * 參數layout:包裹視圖的資源文件id
    * 參數c:數據庫的Cursor對象
    * 參數from:需要的字段名數組
    * 參數to:與from對應的要綁定的視圖id數組
    * 參數flags:定義CursorAdapter的行爲,FLAG_REGISTER_CONTENT_OBSERVER表示註冊內容觀察者
    */
    SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from,
            int[] to, int flags)
  3. 實例

    /*
    * MainActivity.java中的核心代碼
    * lv爲一個ListView
    *db爲一個SQLiteDatabase對象
    * 數據庫中的表必須要有自增長的字段“_id”,而且查詢時也必須查出它
    * 但是我們可以通過“id as _id”的方式解決我們數據表裏用id用自增的問題
    */
    String sql ="select id as _id,rid from imgs";
        Cursor c = db.rawQuery(sql, null);
        lv.setAdapter(new SimpleCursorAdapter(
                this,
                R.layout.listview_simple,
                c, 
                new String[]{"rid"},
                new int[]{R.id.imgSimple}, CursorAdapter.NO_SELECTION));
    <!--佈局文件同上-->

五、ViewHolder

由於理解還不是很充足,暫時不說,下次更新…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章