1. Adapter基本介绍
Android是完全遵循MVC模式设计的框架,Activity是Controller,layout是View。因为layout五花八门,很多数据都不能直接绑定上去,所以Android引入了Adapter这个机制作为复杂数据的展示的转换载体,所以各种Adapter只不过是转换的方式和能力不一样而已
图解:
- Model:通常可以理解为数据,负责执行程序的核心运算与判断逻辑,通过view获得用户 输入的数据,然后根据从数据库查询相关的信息,最后进行运算和判断,再将得到的结果交给view来显示
- view:用户的操作接口,说白了就是GUI,应该使用哪种接口组件,组件间的排列位置与顺序都需要设计
- Controller:控制器,作为model与view之间的枢纽,负责控制程序的执行流程以及对象之间的一个互动
Adapter则是中间的这个Controller的部分: Model(数据) —> Controller(以什么方式显示到)—> View(用户界面) 这就是简单MVC组件的简单理解!
- BaseAdapter:抽象类,实际开发中我们会继承这个类并且重写相关方法,用得最多的一个Adapter
- ArrayAdapter:支持泛型操作,最简单的一个Adapter,只能展现一行文字~
- SimpleAdapter:同样具有良好扩展性的一个Adapter,可以自定义多种效果
- SimpleCursorAdapter:用于显示简单文本类型的listView,一般在数据库那里会用到,不过有点过时, 不推荐使用!
(Adapter一般需要结合ListView,GridView等控件)
1.1 ArrayAdapter
列表的显示需要三个要素:
- ListView等控件: 用来展示列表的View
- 适配器: 用来把数据映射到ListView上的中介
- 数据 具体的将被映射的字符串,图片,或者基本组件
示例:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//要显示的数据
String[] strs = {"基神","B神","翔神","曹神","J神"};
//创建ArrayAdapter适配器
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.simple_expandable_list_item_1,strs);
//获取ListView对象,通过调用setAdapter方法为ListView设置Adapter设置适配器
ListView list_test = (ListView) findViewById(R.id.list_test); //展示列表的View
list_test.setAdapter(adapter);
}
}
上述代码使用了ArrayAdapter(Context context, int textViewResourceId, List<T> objects)
来装配数据,要装配这些数据就需要一个连接ListView视图对象和数组数据的适配器来两者的适配工作,ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_1是系统定义好的布局文件只显示一行文字,数据源(一个List集合)。同时用setAdapter()
完成适配的最后工作
除了上述用java代码创建,还可以写到一个数组资源文件中:
- 在在res/valuse下创建一个数组资源的xml文件,例如**arrays.xml
<resources>
<string-array name="myarray">
<item>语文</item>
<item>数学</item>
<item>英语</item>
<item>体育</item>
</string-array>
</resources>
- 在布局的ListView设置:
<ListView
android:id="@+id/list_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/myarray" />
或者不在布局的ListView中设置,可以在java代码中添加:
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.myarray,android.R.layout.simple_expandable_list_item_1);
ListView list_test = (ListView) findViewById(R.id.list_test);
list_test.setAdapter(adapter);
前述最开始的java代码也可以改写为:
List<String> data = new ArrayList<String>();
data.add("基神");
data.add("B神");
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.simple_expandable_list_item_1,data);
前述实例化ArrayAdapter的第二个参数:android.R.layout.simple_expandable_list_item_1
等都为系统给定的模版
- simple_list_item_1 : 单独一行的文本框
- simple_list_item_2 : 两个文本框组成
- simple_list_item_checked : 每项都是由一个已选中的列表项
- simple_list_item_multiple_choice : 都带有一个复选框
- simple_list_item_single_choice : 都带有一个单选钮
1.2 SimpleAdapter
当ListView等控件中只需要显示一个数据时,使用ArrayAdapter这个适配器很方便,但是如果每一行显示多行数据,ArrayAdapter就不能满足需求,这时候可以使用SimpleAdapter,可以让每一行显示多项数据。
SimpleAdapter只有一个构造函数:
public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
data表示的是List数据源,其中List中的元素都是Map类型,并且Map的key是String类型,Map的value可以是任意类型,我们一般使用
HashMap<String, Object>
作为List中的数据项。
resource表示数据项UI所对应的layout文件,布局文件中至少应包含那些在to中定义了的ID
每个数据项对应一个Map,from表示的是Map中key的数组
数据项Map中的每个key都在layout中有对应的View,to表示数据项对应的View的ID数组。
示例:
- 首先编写一个列表项目每一项的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 定义一个用于显示头像的ImageView -->
<ImageView
android:id="@+id/imgtou"
android:layout_width="64dp"
android:layout_height="64dp"
android:baselineAlignBottom="true"
android:paddingLeft="8dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:textColor="#1D1D1C"
android:textSize="20sp" />
<TextView
android:id="@+id/says"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8px"
android:textColor="#B4B4B9"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
- 接着修改MainActivity
public class MainActivity extends AppCompatActivity {
private String[] names = new String[]{"B神", "基神", "曹神"};
private String[] says = new String[]{"无形被黑,最为致命", "大神好厉害~", "我将带头日狗~"};
private int[] imgIds = new int[]{R.mipmap.ic_launcher, R.mipmap.ic_launcher, R.mipmap.ic_launcher};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Map<String, Object>> listitem = new ArrayList<Map<String, Object>>();
for (int i = 0; i < names.length; i++) {
Map<String, Object> showitem = new HashMap<String, Object>();
showitem.put("touxiang", imgIds[i]);
showitem.put("name", names[i]);
showitem.put("says", says[i]);
listitem.add(showitem);
}
//创建一个simpleAdapter
SimpleAdapter myAdapter = new SimpleAdapter(getApplicationContext(), listitem, R.layout.list_item, new String[]{"touxiang", "name", "says"}, new int[]{R.id.imgtou, R.id.name, R.id.says});
ListView listView = (ListView) findViewById(R.id.list_test);
listView.setAdapter(myAdapter);
}
}