Android Adapter:ArrayAdapter篇

版权声明:本文为博主原创文章,未经博主允许不得转载。
微博:厉圣杰
源码:AndroidDemo/Notification
文中如有纰漏,欢迎大家留言指出。

这是Android Adapter系列文章的第一篇,该系列主要会讲到如下几种Adapter。

ArrayAdapter是BaseAdapter的一个具体实现,可直接使用泛型进行构造,能像List一样直接对Adapter进行增删操作。

ArrayAdapter的构造函数

ArrayAdapter共有6个构造函数,前5种都是调用最后一个构造函数:

public ArrayAdapter(@NonNull Context context, @LayoutRes int resource)

public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@IdRes int textViewResourceId) public ArrayAdapter(@NonNull Context context, @LayoutRes int resource, @NonNull T[] objects) public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@IdRes int textViewResourceId, @NonNull T[] objects) public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@NonNull List<T> objects) public ArrayAdapter(@NonNull Context context, @LayoutRes int resource,
@IdRes int textViewResourceId, @NonNull List<T> objects)

ArrayAdapter特性

默认情况下,ArrayAdapter期望布局文件里只有一个TextView,连Layout都不能包含(构造方法1、3、5)。如果你想使用复杂的布局,则你必须向构造函数传递一个field id,即布局中对应TextView的id。如果想实现更复杂的布局,那么你就得重写BaseAdapter的getView(int, View, ViewGroup)方法返回你需要的View。这就是实现泛型操作带有List功能的Adapter了。

ArrayAdapter会调用List中对象的toString()方法,所以可以通过重写Object的toString()方法来控制TextView的显示。

其实,以上特性查看ArrayAdapter的源码就可以看出来了。ArrayAdapter的getView(int, View, ViewGroup)方法最终调用了createViewFromResource(inflater, position, convertView, parent, resource)方法,源码如下:

private @NonNull View createViewFromResource(@NonNull LayoutInflater inflater, int position, @Nullable View convertView, @NonNull ViewGroup parent, int resource) {
final View view;
final TextView text; if (convertView == null) {
view = inflater.inflate(resource, parent, false);
} else {
view = convertView;
} try {
//mFieldId即为构造函数中的textViewResourceId
if (mFieldId == 0) {
// If no custom field is assigned, assume the whole resource is a TextView
text = (TextView) view;
} else {
// Otherwise, find the TextView field within the layout
text = (TextView) view.findViewById(mFieldId); if (text == null) {
throw new RuntimeException("Failed to find view with ID "
+ mContext.getResources().getResourceName(mFieldId)
+ " in item layout");
}
}
} catch (ClassCastException e) {
Log.e("ArrayAdapter", "You must supply a resource ID for a TextView");
throw new IllegalStateException(
"ArrayAdapter requires the resource ID to be a TextView", e);
} final T item = getItem(position);
if (item instanceof CharSequence) {
text.setText((CharSequence) item);
} else {
//如果想控制ArrayAdapter显示,复写toString()即可
text.setText(item.toString());
} return view;
}

ArrayAdapter的List特性

ArrayAdapter中的数组操作方法可以总结如下,其都是通过对构造函数或者后期添加的List数据进行增删操作来实现的,具体可以参看源码。

//添加一个对象到ArrayAdapter
void add(T object); //将数组全部添加到ArrayAdapter
void addAll(@NonNull Collection<? extends T> collection); //将数组全部添加到ArrayAdapter
void addAll(T ... items); //插入新条目到指定位置
void insert(@Nullable T object, int index); //清除所有元素
void clear(); //移出一条从数组,这里并没有指定位置
void remove(T object); //控制当执行add(T), insert(T, int), remove(T), clear()等的操作时,是否自动执行`notifyDataSetChanged()`自动刷新UI。当其为false时,需要手动调用`notifyDataSetChanged()`方法
void setNotifyOnChange(boolean notifyOnChange); //对ArrayAdapter显示的数据进行排序
void sort(Comparator<? super T> comparator);

Demo时间

ArrayAdapter的实现原理讲的差不多了,那么接下来就是demo时间了。

ArrayAdapter的最简单使用

ArrayAdapter的最简单使用应该就属构造函数1、3、5,一赤裸裸的Textview布局,一数组足矣。
代码真心简单的不要不要的,如果想尝试自定义简单ArrayAdapter的布局可以参考custom_simplest_list_item.xml

SimplestArrayAdapterActivity.java:

public class SimplestArrayAdapterActivity extends Activity {

    private ListView mLv;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simplest_array_adapter); mLv = (ListView) findViewById(R.id.lv);
mLv.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Util.generateString(10)));
//此处为自定义的simple_list_item
//mLv.setAdapter(new ArrayAdapter<String>(this, R.layout.custom_simplest_list_item, Util.generateString(10)));
}
}

activity_simplest_array_adapter.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SimplestArrayAdapterActivity"> <ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView> </LinearLayout>

custom_simplest_list_item.xml:

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

ArrayAdapter的进阶使用

ArrayAdapter的进阶使用其实不比上面的demo难多少,只是这里调用的构造函数2、4、6中的一种,只需要自定义一个包含TextView的布局,将布局id和TextView的id传递给ArrayAdapter即可。

//替换此处
mLv.setAdapter(new ArrayAdapter<String>(this,R.layout.custom_list_item,R.id.tv_i_am_textview, Util.generateString(10)));

custom_list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context="com.littlejie.adapter.MiddleArrayAdapterActivity"> <ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher" /> <TextView
android:id="@+id/tv_i_am_textview"
android:layout_width="match_parent"
android:layout_height="30dp"
android:gravity="center" />
</LinearLayout>

运行结果如下:

ArrayAdapter的超阶使用

ArrayAdapter实现复杂布局其实也很简单,只需要重写getView(int, View, ViewGroup)方法即可,其余和前两个例子没啥区别。getView(int, View, ViewGroup)后面讲BaseAdapter的时候会详细讲。

HardestArrayAdapterActivity.java:

public class HardestArrayAdapterActivity extends Activity {

    private ListView mLv;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hardest_array_adapter); mLv = (ListView) findViewById(R.id.lv);
mLv.setAdapter(new MyArrayAdapter(this, generateData(10)));
} private List<Student> generateData(int num) {
List<Student> students = new ArrayList<>();
for (int i = 0; i < num; i++) {
Student student = new Student();
student.setName("学生 " + i);
student.setGender(i % 2 == 0 ? "男" : "女");
student.setScore(String.valueOf(100 - i));
students.add(student);
}
return students;
} /**
* 自定义ArrayAdapter,重写getView(int, View, ViewGroup)方法
*/
private class MyArrayAdapter extends ArrayAdapter<Student> { private List<Student> mStudents; public MyArrayAdapter(Context context, List<Student> objects) {
super(context, 0, objects);
mStudents = objects;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.custom_hardest_list_item, null);
TextView tvName = (TextView) convertView.findViewById(R.id.tv_name);
TextView tvGender = (TextView) convertView.findViewById(R.id.tv_gender);
TextView tvScore = (TextView) convertView.findViewById(R.id.tv_score); Student student = mStudents.get(position);
tvName.setText("姓名:" + student.getName());
tvGender.setText("性别:" + student.getGender());
tvScore.setText("成绩:" + student.getScore());
return convertView;
}
} /**
* 定义学生对象,存放姓名、性别、成绩
*/
private class Student {
private String name;
private String gender;
private String score; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getGender() {
return gender;
} public void setGender(String gender) {
this.gender = gender;
} public String getScore() {
return score;
} public void setScore(String score) {
this.score = score;
} @Override
public String toString() {
return "姓名:" + name + "\n性别:" + gender + "\n成绩:" + score;
}
}
}

custom_hardest_list_item.xml:

<?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="vertical"> <TextView
android:id="@+id/tv_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <TextView
android:id="@+id/tv_gender"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <TextView
android:id="@+id/tv_score"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

代码运行结果如下:

其实这个demo也可以用最简单的方式来实现,那就是重写Student类的toString()方法。

public String toString() {
return "姓名:" + name + "\n性别:" + gender + "\n成绩:" + score;
}

ArrayAdapter的List操作

话不多说,直接上代码。

ListActionActivity.java:

public class ListActionActivity extends Activity implements View.OnClickListener {

    private Button mBtnAdd, mBtnAddAll;
private Button mBtnInsert, mBtnClear;
private Button mBtnRemove, mBtnSort;
private Button mBtnSetNotifyOnChangeOpen, mBtnSetNotifyOnChangeClose;
private ListView mLv;
private ArrayAdapter<String> mAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_action); mBtnAdd = (Button) findViewById(R.id.btn_add);
mBtnAddAll = (Button) findViewById(R.id.btn_addAll);
mBtnInsert = (Button) findViewById(R.id.btn_insert);
mBtnClear = (Button) findViewById(R.id.btn_clear);
mBtnRemove = (Button) findViewById(R.id.btn_remove);
mBtnSort = (Button) findViewById(R.id.btn_sort);
mBtnSetNotifyOnChangeOpen = (Button) findViewById(R.id.btn_setNotifyOnChangeOpen);
mBtnSetNotifyOnChangeClose = (Button) findViewById(R.id.btn_setNotifyOnChangeClose); mLv = (ListView) findViewById(R.id.lv);
mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, Util.generateString(10));
mLv.setAdapter(mAdapter); mBtnAdd.setOnClickListener(this);
mBtnAddAll.setOnClickListener(this);
mBtnInsert.setOnClickListener(this);
mBtnClear.setOnClickListener(this);
mBtnRemove.setOnClickListener(this);
mBtnSort.setOnClickListener(this);
mBtnSetNotifyOnChangeOpen.setOnClickListener(this);
mBtnSetNotifyOnChangeClose.setOnClickListener(this);
} @Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_add:
add();
break;
case R.id.btn_addAll:
addAll();
break;
case R.id.btn_insert:
insert();
break;
case R.id.btn_clear:
clear();
break;
case R.id.btn_remove:
remove();
break;
case R.id.btn_sort:
sort();
break;
case R.id.btn_setNotifyOnChangeOpen:
setNotifyOnChangeOpen();
break;
case R.id.btn_setNotifyOnChangeClose:
setNotifyOnCHangeClose();
break;
}
} private void add() {
String add = "我是通过add()添加进来的";
mAdapter.add(add);
} private void addAll() {
List<String> addAll = new ArrayList<>();
addAll.add("addAll-item1");
addAll.add("addAll-item2");
mAdapter.addAll(addAll);
} private void insert() {
String insert = "insert到第二个位置";
mAdapter.insert(insert, 1);
} private void clear() {
mAdapter.clear();
} private void remove() {
mAdapter.remove("item 1");
} private void sort() {
} private void setNotifyOnChangeOpen() {
mAdapter.setNotifyOnChange(true);
} private void setNotifyOnCHangeClose() {
mAdapter.setNotifyOnChange(false);
}
}

activity_action_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MiddleArrayAdapterActivity"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:id="@+id/btn_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="add" /> <Button
android:id="@+id/btn_addAll"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="addAll" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:id="@+id/btn_insert"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="insert" /> <Button
android:id="@+id/btn_clear"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="clear" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:id="@+id/btn_remove"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="remove" /> <Button
android:id="@+id/btn_sort"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="sort" />
</LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:id="@+id/btn_setNotifyOnChangeOpen"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="setNotifyOnChangeOpen" /> <Button
android:id="@+id/btn_setNotifyOnChangeClose"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="setNotifyOnChangeClose" />
</LinearLayout> <ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView> </LinearLayout>

好了,ArrayAdapter的用法应该都讲完了。找个时间把Demo的代码放到git上去~本系列文章会持续更新,欢迎关注~

觉得文章不错的话,就赏我一罐可乐吧~

ArrayAdapter的更多相关文章

  1. Android应用项目中BaseAdapter、SimpleAdapter和ArrayAdapter中的三种适配器

    一.写在前面: 本次我们来讲解一下Android应用中三个适配器:BaseAdapter.SimpleAdapter和ArrayAdapter.其中常见的是BaseAdapter,也是个人推荐使用的适 ...

  2. Android ListView ArrayAdapter 的简单使用

    前面写了3篇关于android的文章,其中的演示程序都写在了一个工程中,当时为了方便测试就在启动页MainActivity中放了3个按钮,点击不同的按钮进入不同的示例程序页面,MainActivity ...

  3. 深入理解使用ListView时ArrayAdapter、SimpleAdapter、BaseAdapter的原理

    在使用ListView的时候,我们传给setAdapter方法的Adapter通常是ArrayAdapter.SimpleAdapter.BaseAdapter,但是这几个Adapter内部究竟是什么 ...

  4. Android学习---ListView的点击事件,simpleAdapter和arrayadapter,SimpleCursoAdapter的原理和使用

    如题,本文将介绍 listview的点击事件,simpleAdapter和arrayadapter的原理和使用. 1.ListView的注册点击事件 //注册点击事件 personListView.s ...

  5. Android之ListView——ArrayAdapter的用法学习

    当我们使用ListView时,必不可少的便会使用到adapter,adapter的用处就像是一个水管接口,把你想展现的数据与你希望展现的布局样式通过某种协定结合起来. ArrayAdapter针对每个 ...

  6. 注意ArrayAdapter的Add()方法

    ArrayAdapter类可以作为ListView等的适配器资源,并且可以动态向适配器中添加新的数据,这就是ArrayAdapter.Add()方法的作用.但是在使用该方法时如果出错,那就需要检查Ar ...

  7. Android 常用数据适配器ArrayAdapter

    接着上篇文章<Android 采用Layout Inflater创建一个View对象>,本文采用常用数据适配器ArrayAdapter 新建项目后,在layout文件夹下新建list_it ...

  8. 无废话Android之listview入门,自定义的数据适配器、采用layoutInflater打气筒创建一个view对象、常用数据适配器ArrayAdapter、SimpleAdapter、使用ContentProvider(内容提供者)共享数据、短信的备份、插入一条记录到系统短信应用(3)

    1.listview入门,自定义的数据适配器 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/and ...

  9. [安卓] 6、列表之ArrayAdapter适配

    这个和以前的几个都有点不同,首先这个不用在xml中写对应的控件,而是直接在activity中将整个list实现的:首先要实例化列表和用于存储数据的数组list[9-10],第12-14行放list里加 ...

随机推荐

  1. jQuery之ajax实现篇

    jQuery的ajax方法非常好用,这么好的东西,你想拥有一个属于自己的ajax么?接下来,我们来自己做一个简单的ajax吧. 实现功能 由于jq中的ajax方法是用了内置的deferred模块,是P ...

  2. Bootstrap 模态框(Modal)插件

    页面效果: html+js: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  3. My TWI

    前言 对TWI没有什么特别的印象,因为有一个更出名的TWU,而我去年又刚好错过了它,因此TWU的光辉完全掩盖了TWI.对TWI印象最深的是在邮件中看到的38th北京的这期,看到他们的图文记录,在圈子中 ...

  4. nginx源码分析之模块初始化

    在nginx启动过程中,模块的初始化是整个启动过程中的重要部分,而且了解了模块初始化的过程对应后面具体分析各个模块会有事半功倍的效果.在我看来,分析源码来了解模块的初始化是最直接不过的了,所以下面主要 ...

  5. Mysql存储引擎及选择方法

    0x00 Mysql数据库常用存储引擎 Mysql数据库是一款开源的数据库,支持多种存储引擎的选择,比如目前最常用的存储引擎有:MyISAM,InnoDB,Memory等. MyISAM存储引擎 My ...

  6. 【深入Java虚拟机】之四:类加载机制

    类加载过程     类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.它们开始的顺序如下图所示: 其中类加载的过程包括了加载.验 ...

  7. 初识npm

    一.npm简介: npm全称为Node Package Manager,是一个基于Node.js的包管理器,也是整个Node.js社区最流行.支持的第三方模块最多的包管理器. npm的初衷:JavaS ...

  8. Linux 利用Google Authenticator实现ssh登录双因素认证

    1.介绍 双因素认证:双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统.双因素认证是一种采用时间同步技术的系统,采用了基于时间.事件和密钥三变量而产生的一 ...

  9. Configure a bridged network interface for KVM using RHEL 5.4 or later?

    environment Red Hat Enterprise Linux 5.4 or later Red Hat Enterprise Linux 6.0 or later KVM virtual ...

  10. Hello bokeyuan!

    一个学习技术的年轻人 从2016/09/03进入大学学习计算机科学与技术这门学科,我已经学习了4个月了,大学的生活很枯燥,很麻烦,很多事,与我想象中的大学有很大的区别.但是这都不会影响我想要成为一个技 ...