Android學習_使用Adapter創建ListView

Adapter本身只是一個接口,它派生了ListAdapter和SpinnerAdapter兩個子接口。

Adapter常用的實現類如下:
–ArrayAdapter:簡單、易用的Adapter,通常用於將數組或List集合的多個值包裝成多個列表項。
–SimpleAdapter:不簡單、功能強大的Adapter,可用於將List集合的多個對象包裝成多個列表項。
–SimpleCursorAdapter:與SimpleAdapter基本相似,只是用於包裝Cursor提供的數據。
–BaseAdapter:通常用於被擴展。擴展BaseAdapter可以對各列表項進行最大限度的定製。

通過實例介紹

使用ArrayAdapter創建ListView

//此佈局文件定義了兩個ListView,但這兩個ListView都沒有指定android:entries屬性,這意味着都需要通過Adapter來提供列表項
 <!--設置使用紅色的分隔條-->
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/list1"
        android:divider="#f00"
        android:dividerHeight="2px"
        android:headerDividersEnabled="false"/>
    <!--設置使用綠色的分隔條-->
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/list2"
        android:divider="#0f0"
        android:dividerHeight="2px"
        android:headerDividersEnabled="false"/>

Activity提供Adapter,Adapter決定ListView所顯示的列表項

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView list1 = (ListView) findViewById(R.id.list1);
        //定義一個數組
        String[] arr1 = {"孫悟空", "牛魔王", "至尊寶"};
        //將數組包裝爲ArrayAdapter
        ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this, R.layout.array_item, arr1);
        //爲ListView設置Adapter
        list1.setAdapter(adapter1);

        ListView list2 = (ListView) findViewById(R.id.list2);
        //定義一個數組
        String[] arr2 = {"eclipse", "android studio", "vs2013"};
        //將數組包裝爲ArrayAdapter
        ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this, R.layout.checked_item, arr2);
        //爲ListView設置Adapter
        list2.setAdapter(adapter2);
       }
}

創建ArrayAdapter時必須指定以下三個參數:
–Context:代表訪問整個Android應用的接口。幾乎創建所有組件都需要傳入Context對象。如上面代碼使用this。
–textViewResourceld:資源ID,該資源代表一個TextView,該TextView組件將作爲ArrayAdapter的列表項組件。
–數組或list:該數組或List兼顧則爲多個列表項提供數據。

從上面不難看出,創建ArrayAdapter時傳入的第二個參數控制每個列表項的組件,第三個參數則負責爲列表提供數據。該數組或List包含多少個元素,就將生成多少個列表項,每個列表項都是TextView組件,TextView組件顯示的文本由數組或List的元素提供。

每個列表項的組件外觀由下面佈局文件控制:

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

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/TextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="24dp"
    android:padding="10px"
    android:textColor="#f0f"
    android:shadowDx="4"
    android:shadowDy="4"
    android:shadowRadius="2">

</TextView>

基於ListActivity實現列表

如果程序的窗口僅僅需要顯示一個列表,則可以直接讓Activity繼承ListActivity來實現,ListActivity的子類無須調用setContentView()方法來顯示某個界面,而是可以直接傳入一個內容Adapter,ListActivity的子類就呈現出一個列表。

public class TwoActivity extends ListActivity {

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //無需佈局文件
        String[] arr = {"丁一", "王二", "張三", "李四"};
        //創建ArrayAdapter對象
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_multiple_choice, arr);
        //設置該窗口顯示列表
        setListAdapter(adapter);

        //用setchoicemode方法將選擇方式設置爲CHOICE_MODE_MULTIPLE,即可實現多選的選中效果。
        final ListView listView = getListView();
        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    }
}

使用SimpleAdapter創建ListView

ArrayAdapter雖然簡單、易用,但ArrayAdapter的功能比較有限,它的每個列表項只能是TextView。如果需要實現更復雜的列表項,則可以使用SimpleAdapter。

界面佈局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!--定義一個ListView-->
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/list3"/>
</LinearLayout>

每個列表項的界面佈局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!--定義一個ImageView,用於作爲列表項的一部分-->
    <ImageView
        android:id="@+id/header"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:paddingLeft="10dp"
        android:scaleType="fitCenter"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <!--定義一個TextView,用於作爲列表項的一部分-->
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="40dp"
            android:textColor="#742974"
            android:paddingLeft="10dp"/>
        <!--定義一個TextView,用於作爲列表項的一部分-->
        <TextView
            android:id="@+id/desc"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:paddingLeft="10dp"
            android:singleLine="true"
            android:ellipsize="end"/>
    </LinearLayout>

</LinearLayout>

Activity代碼:

public class ThreeActivity extends AppCompatActivity{

    private String[] names = new String[]{
            "哈利", "皮特", "傑瑞", "湯姆", "川普"};
    private String[] descs = new String[]{
            "頭上帶閃電的天選之人", "被蜘蛛咬的天選之人",
            "一隻脫離了低級趣味的老鼠", "一隻奮鬥的貓",
            "大美興,川普王,川普來了不納糧"
    };
    private int[] imageIds = new int[]{
            R.drawable.hali, R.drawable.zhizhuxia,
            R.drawable.jierui, R.drawable.tangmu,
            R.drawable.chuanpu
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_three);

        //創建一個List集合,List集合的元素是Map
        List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < names.length; i++){

            Map<String, Object> listItem = new HashMap<String, Object>();
            listItem.put("header", imageIds[i]);
            listItem.put("personName", names[i]);
            listItem.put("desc", descs[i]);
            listItems.add(listItem);
        }
        //創建一個SimpleAdapter
        SimpleAdapter simpleAdapter = new SimpleAdapter(this,
                listItems, R.layout.simple_item,
                new String[]{"personName", "header", "desc"},
                new int[]{R.id.name, R.id.header, R.id.desc});
        ListView list = (ListView) findViewById(R.id.list3);
        //爲ListView設置Adapter
        list.setAdapter(simpleAdapter);

        //爲ListView的列表項的單擊事件綁定時間監聽器
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(ThreeActivity.this, names[i] + "被單擊了",Toast.LENGTH_SHORT).show();
                System.out.println(names[i] + "被單機了");
            }
        });
    }
}

上面代碼中還添加了OnItemClickListener單擊事件,需要注意的是,OnItemSelectedListener事件可能會無響應,這是因爲OnItemSelectedListener是用來監聽【選中某一項】的事件,不是【點擊】某一項的事件,雖然點擊能引發選中事件,但不是必然的, 一般用按鍵或者鼠標滾輪移動焦點都會產生這個選中事件。


擴展BaseAdapter實現不存儲列表項的ListView

擴展BaseAdapter可以取得對Adapter最大的控制權:程序要創建多少個列表項,每個列表項的組件都有開發者決定。

佈局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/list4"/>

</LinearLayout>

Activity:

public class FourActivity extends AppCompatActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_four);

        //獲取ListView組件
        ListView list4 = (ListView) findViewById(R.id.list4);
        BaseAdapter adapter = new BaseAdapter() {
            @Override
            public int getCount() {
                //指定一共包含40個選項
                return 40;
            }

            @Override
            public Object getItem(int i) {
                return null;
            }
            //重寫該方法,該方法的返回值將作爲列表項的ID
            @Override
            public long getItemId(int i) {
                return i;
            }
            //重寫該方法,該方法返回的View將作爲列表框
            @Override
            public View getView(int i, View view, ViewGroup viewGroup) {
                //創建一個LinearLayout,並向其中添加兩個組件
                LinearLayout linearLayout = new LinearLayout(FourActivity.this);
                //設置排列方式
                linearLayout.setOrientation(LinearLayout.HORIZONTAL);
                //圖片
                ImageView imageView = new ImageView(FourActivity.this);
                imageView.setImageResource(R.drawable.chuanpu);
                //文本
                TextView textView = new TextView(FourActivity.this);
                textView.setText("第" + (i + 1) + "個列表項");
                textView.setTextSize(20);
                textView.setTextColor(Color.RED);
                linearLayout.addView(imageView);
                linearLayout.addView(textView);
                //返回LinearLayout實例
                return linearLayout;
            }
        };
        list4.setAdapter(adapter);
    }
}

擴展對象需要重寫如下4個方法:
–getCount():該方法的返回值控制該Adapter將會包含多少個列表項。
–getItem(int position):該方法的返回值決定第position處的列表項的內容。
–getItemId(int position):該方法的返回值決定第position處的列表項的ID。
–getView(int position, View convertView, ViewGroup parent):該方法的返回值決定第position處的列表項組件。

上述四個方法中最重要的是第一個和第四個。


以上實現Adapter的方法完全適用於AdapterView的其他子類:GridView、、Spinner、Gallery、AdapterViewFlipper等。

總的來說創建步驟就是兩步:
1.採用四種方式之一創建Adapter。
2.調用AdapterView的setAdapter(Adapter)方法設置Adapter即可。

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