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