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即可。