ListView (3) 之适配器 ArrayAdapter/SimpleAdapter/BaseAdapter
2015-04-16 21:20
211 查看
ListView (3) 之适配器 Adapter
ArrayAdapter/SimpleAdapter/BaseAdapter的使用Android中通过Adapter为AbsListView列表控件提供基础数据,Adapter只是一个接口,它派生了ListAdapter和SpinnerAdapter,其中ListAdapter为AbsListView提供列表,SpinnerAdapter为AbsSpinner提供数据。
ListView、 Adapter、 数据源三者之间的关系图
ArrayAdapter
ArrayAdapter是较为简单快捷的适配器,不需要创建专门的Item布局来填充列表项,通过提供一个String[]类型的数据源,可以直接通过系统自带的布局文件数据源为String[] 的数据集合
String[] list = { "李阳疯狂英语", "AOC", "BBC", "CCTV", "优酷财经" }; // 将数组包装成ArrayAdapter ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,android.R.layout.simple_list_item_single_choice, list); listView.setAdapter(adapter);
ArrayAdapter构造函数,第二个参数为 带有一个TextView系统布局资源ID,TextView的ID为@android:id/text1,点击可查看布局如下
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeightSmall" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:textAppearance="?android:attr/textAppearanceListItemSmall" />
数据源保存在资源文件
// 获取resource资源文件定义好的数组 Resources res = getResources(); String[] arrs = res.getStringArray(R.array.books); // 将数组包装成ArrayAdapter,第二个参数为 带有一个TextView // 布局资源,TextView的ID为@android:id/text1 ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,android.R.layout.simple_list_item_1, arrs); listView.setAdapter(adapter);
SimpleAdapter
通过ArrayAdapter实现的Adapter虽然简单、易用,但功能有限,它只能通过每个列表项是TextView,如果需要实现更复杂的列表项,则可以使用SimpleAdapter。SimpleAdapter并非如名字简单,它的功能很强大,可实现ListView的大部分应用。<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/Img" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/Img" android:gravity="center_vertical" android:layout_marginLeft="20sp"/> <TextView android:id="@+id/country" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/name" android:layout_marginLeft="20sp"/> </RelativeLayout>
package com.example.listview03_simpleadapter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { private String[] names = { "姚明", "Kobe", "贝克汉姆", "加索尔" }; private String[] country = { "中国", "美国", "英国", "西班牙" }; private int[] imgId = { R.drawable.j1a2, R.drawable.j1a4, R.drawable.j1a5,R.drawable.j1a6 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 创建一个List集合,集合元素Map List<Map<String, Object>> listItem = new ArrayList<Map<String, Object>>(); for (int i = 0; i < names.length; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("img", imgId[i]); map.put("name", names[i]); map.put("country", country[i]); listItem.add(map); } // 创建Adapter实例 SimpleAdapter adapter = new SimpleAdapter(MainActivity.this, listItem,R.layout.item, new String[] { "img", "name", "country" },new int[] { R.id.Img, R.id.name, R.id.country }); ListView listView = (ListView) findViewById(R.id.listViewId); listView.setAdapter(adapter); } }
BaseAdapter使用及优化
【重点】下面重点介绍,BaseAdapter是一个实现了ListAdapter和SpinnerAdapter接口的抽象类,可用于为ListView和Spinner提供数据适配器。public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
关于BaseAdapter的使用,相信一张图足以说明
[图片来源:鸿洋大神的博客]
(/article/1580267.html)
继承自BaseAdapter的自定义适配器
public class MyListAdapter extends BaseAdapter { private Context context; /** 数据源 */ private List<User> mList; private LayoutInflater inflater; public MyListAdapter(Context context, List<User> mList) { super(); this.context = context; this.mList = mList; inflater = LayoutInflater.from(context); } @Override public int getCount() { return mList.size(); } @Override public User getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { return null; } }
从上代码片段中可以看到,我们自定义的数据适配器继承子BaseAdapter,需要复写下面四个方法
getCount() —获取数据源个数
getItem(int position) —获取指定position的数据实体
getItemId(int position) —获取数据列表的行编号,一般返回position
getView(int position, View convertView, ViewGroup parent) —此方法最为重要,返回一个显示在数据列表中View;
在getView方法加载指定XML布局文件,设置每个Item显示内容,绑定Item中各个控件的监听事件,具体操作以下代码块
getView方法 convertView的复用
首先,getView的三个参数分别代表: 序号(位置)、列表中一个ITEM的显示视图、view依附的父视图Android中有个叫做Recycler(反复循环器)的构件,下图是它的工作原理:
convert的复用:一共有200条,每屏可以显示7条数据,初次加载并不会一次性调用200次getView方法,只会调用前7次,生成7个convertView显示到页面上, 当页面滑动第一个Item被划出屏幕外,此时划出屏幕外的Item1存在convertView中,convertView是一个xml资源生成的View,当底部有新的Item划入屏幕,此时convertView持有了划出屏幕外的view,可以拿来直接使用,而减少了inflate资源的次数。也就是说利用convertView的复用,虽然数据源总个数为200,但只有第一次 执行inflate加载xml资源。
@Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if (view == null) { view = inflater.inflate(R.layout.item_simple, parent, false); } TextView tvName = (TextView) view.findViewById(R.id.name); TextView tvCity = (TextView) view.findViewById(R.id.country); tvName.setText(mList.get(position).getName()); tvCity.setText(mList.get(position).getCountry()); Log.i("getView", "pos:" + position); return view; }
ViewHolder优化findView次数
从上述代码片中,通过convertView复用减少了inflate加载资源的次数,可每次执行getView方法时,每次通过findViewById去找convertView的所用子控件,在反复滑动时会不断调用getView方法,所以同时就会反复调用findViewById方法。为了提高性能,减少findViewById次数,我们这里就用到了ViewHolder来持有convertView的每一个子控件,以setTag的形式和convertView绑定,需要时再从convertView.getTag()中取出,避免了反复findViewById的情况。private class ViewHolder { public TextView tvName; public TextView tvCity; }
@Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if (view == null) { ViewHolder viewHolder = new ViewHolder(); view = inflater.inflate(R.layout.item_simple, parent, false); // 通过ViewHolder持有view中的子控件 viewHolder.tvName = (TextView) view.findViewById(R.id.name); viewHolder.tvCity = (TextView) view.findViewById(R.id.country); // 再通过setTag的形式和view绑定 view.setTag(viewHolder); } ViewHolder viewHolder = (ViewHolder) view.getTag(); viewHolder.tvName.setText(mList.get(position).getName()); viewHolder.tvCity.setText(mList.get(position).getCountry()); return view; }
相关文章推荐
- ListView 的三种适配器 BaseAdapter ArrayAdapter SimpleAdapter(3)
- ListView 的三种适配器 BaseAdapter ArrayAdapter SimpleAdapter(1)
- ListView 的三种适配器 BaseAdapter ArrayAdapter SimpleAdapter(2)
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
- Android中ListView与适配器ArrayAdapter,SimpleAdapter,定义BaseAdapter适配器,ListView添加headerView,ListView滚动到最后一项
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段(转)
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
- ListView的三大适配器ArrayAdapter,SimpleAdapter,MyAdapter
- 【Android】Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
- [转]Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
- Android-ListView详解(SimpleAdapter,ArrayAdapter,BaseAdapter,OnItenClickListener,OnScrollListener)
- Android适配器之ArrayAdapter、SimpleAdapter和BaseAdapter的简单用法与有用代码片段
- 3.2列表的使用listview与BaseAdapter、simpleAdapter、ArrayAdapter
- 安卓:将数据库中的数据查询出来用adapter(SimpleAdapter,SimpleCursorAdapter,自定义适配器CursorAdapter)绑定到listview上
- 安卓开发_浅谈ListView(SimpleAdapter数组适配器)
- Android实现ListView过滤功能,继承于BaseAdapter,非ArrayAdapter