ListView与Adapter
来源:互联网 发布:尽人事知天命下一句 编辑:程序博客网 时间:2024/05/19 03:44
ListView是用来交互和展示数据的,但是数据的类型很多,如果让ListView为每一种数据都进行适配的话那么ListView是比较臃肿的,所以就需要Adapter去帮助我们适配数据源。
Adapter是一个接口,Adapter常用的实现类如下:
ArrayAdapter: 简单,易用的Adapter,通常用于将数组或者List集合的多个值包装成多个列表项。
SimpleAdapter: 并不简单,功能强大的Adapter,可用于将List集合的多个对象包装成多个列表项。
SimpleCursorAdapter:与SimpleAdapter基本相似,只是用于包装Cursor提供的数据。
BaseAdapter: 通常用于被扩展。扩展BaseAdapter可以对各列表项进行最大限度的定制。
listView与ArrayAdapter
使用步骤:
1. 创建并绑定ListView。
2. 创建ArrayAdapter。
3. 设置ListView的Adapter。
ArrayAdapter有两个构造方法:
ArrayAdapter(Context context, int textViewResourceId, List objects)
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
其中resource用于布局文件资源。textViewResourceId设置TextView样式。
textViewResourceId常用的参数为:
simple_list_item_1: 每个列表项都是一个普通的TextView。
simple_list_item_2: 有两个TextView,分两行显示。
simple_list_item_multiple_choice: 每个列表项都带多选框。
simple_list_item_single_choice :每个列表项都带单选框。
示例程序
public class MainActivity extends Activity { private String[] data = {"apple", "banana", "orange", "watermelon", "pear"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ArrayAdapter<String> adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, data); ListView listView = (ListView) findViewById(R.id.list_view); listView.setAdapter(adapter); }}
xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="match_parent"></ListView></LinearLayout>
ListView与SimpleAdapter
通过ArrayAdapter实现Adapter虽然简单,但是ArrayAdapter得功能比较有限。如果需要实现更复杂的功能就需要使用SimpleAdapter了。
SimpleAdapter的构造方法为:
public SimpleAdapter(Context context, List<? extends Map<String, ?>> data, @LayoutRes int resource, String[] from, @IdRes int[] to)
第二个参数: 该集合中每一个Map<String, ?>
对象生成一个列表项。
第三个参数: 指定一个界面布局的ID。
第四个参数: 决定提取Map<String , ?>
中的对象的哪些key对应的value来生成列表项。
第五个参数: 决定填充哪些组件。
示例程序
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="horizontal"> <ListView android:id="@+id/list_view" android:layout_width="match_parent" android:layout_height="wrap_content"></ListView></LinearLayout>
新建一个simple_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/header" android:paddingLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/name" android:textSize="20dp" android:textColor="#f0f" android:paddingLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/desc" android:textSize="14dp" android:paddingLeft="10dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout></LinearLayout>
MainActivity
public class MainActivity extends Activity { private String[] name = {"apple", "banana", "orange", "watermelon", "pear"}; private String[] descs = {"苹果好吃", "香蕉好吃", "橘子好处", "西瓜好吃", "梨好吃"}; //随便找的图标 private int[] imageId = new int[]{R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.content_main); List<Map<String, Object>> listItems = new ArrayList<>(); for (int i = 0; i < name.length; i++) { Map<String, Object> listItem = new HashMap<>(); listItem.put("header", imageId[i]); listItem.put("name", name[i]); listItem.put("desc", descs[i]); listItems.add(listItem); } SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.simple_item, new String[]{"name", "header", "desc"}, new int[]{R.id.name, R.id.header, R.id.desc}); ListView list = (ListView) findViewById(R.id.list_view); list.setAdapter(simpleAdapter); }}
扩展BaseAdapter
扩展BaseAdapter需要重写4个方法。
getCount():该方法的返回值控制该Adapter将会包含多少个列表项。
getItem(int position):该方法的返回值决定第position处的列表项的内容。
getItemId(int position):该方法的返回值决定第position处的列表项的ID。
getView(int position, View convertView, ViewGroup parent):这里最重要的方法,该方法的返回值决定第position处的列表项组件。
public class MyAdapter extends BaseAdapter { @Override public int getCount() { return 0; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { return null; }}
getView的优化
要理解getView的优化首先应理解 Recycle机制。这里推荐郭霖的 Android ListView工作原理完全解析,带你从源码的角度彻底理解
没有任何优化:
@Override public View getView(int position, View convertView, ViewGroup parent) { View item = mInflater.inflate(R.layout.list_item, null); ImageView img = (ImageView)item.findViewById(R.id.img) TextView title = (TextView)item.findViewById(R.id.title); TextView info = (TextView)item.findViewById(R.id.info); img.setImageResource(R.drawable.ic_launcher); title.setText("Hello"); info.setText("world"); return item; }
每加载一个数据时都会重新创建View和绑定资源操作。一旦数据量多的时候会严重影响性能。
优化一:利用缓存中的View也就是convertView
public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null) { convertView = mInflater.inflate(R.layout.list_item, null); } ImageView img = (ImageView)convertView.findViewById(R.id.img) TextView title = (TextView)convertView.findViewById(R.id.title); TextView info = (TextView)ConvertView.findViewById(R.id.info); img.setImageResource(R.drawable.ic_launcher); title.setText("Hello"); info.setText("world"); return convertView; }
优化二:利用静态类优化绑定资源的操作
//在外面先定义,ViewHolder静态类 static class ViewHolder { public ImageView img; public TextView title; public TextView info; }//然后重写getView @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.list_item, null); holder.img = (ImageView)item.findViewById(R.id.img) holder.title = (TextView)item.findViewById(R.id.title); holder.info = (TextView)item.findViewById(R.id.info); convertView.setTag(holder); }else { holder = (ViewHolder)convertView.getTag(); holder.img.setImageResource(R.drawable.ic_launcher); holder.title.setText("Hello"); holder.info.setText("World"); } return convertView; }
示例程序
activicy_main和simple_item直接用simpleAdapter示例程序的。
MainActivity:
public class MainActivity extends Activity { private List<Map<String, Object>> data; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.content_main); data = getData(); MyAdapter myAdapter = new MyAdapter(this); ListView list = (ListView) findViewById(R.id.list_view); list.setAdapter(myAdapter); } private List<Map<String, Object>> getData(){ List<Map<String, Object>> listItems = new ArrayList<>(); for (int i = 0; i < 20; i++) { Map<String, Object> listItem = new HashMap<>(); listItem.put("header", R.drawable.ic_launcher); listItem.put("name", i + "Android机器人"); listItem.put("desc", "Android机器人"); listItems.add(listItem); } return listItems; } static class ViewHolder{ public ImageView header; public TextView name; public TextView desc; } public class MyAdapter extends BaseAdapter { private LayoutInflater mInflater; public MyAdapter(Context context){ this.mInflater = LayoutInflater.from(context); } @Override public int getCount() { return 20; } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null){ holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.simple_item, null); holder.header = (ImageView) convertView.findViewById(R.id.header); holder.name = (TextView) convertView.findViewById(R.id.name); holder.desc = (TextView) convertView.findViewById(R.id.desc); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } holder.header.setBackgroundResource((Integer) data.get(position).get("header")); holder.name.setText((String) data.get(position).get("name")); holder.desc.setText((String) data.get(position).get("desc")); return convertView; } }}
参考书籍博客
《第一行代码》
《Android疯狂讲义》第三版
Android ListView工作原理完全解析,带你从源码的角度彻底理解
android应用开发全程实录-你有多熟悉listview?
android ListView详解
Android杂谈–ListView之BaseAdapter的使用
博客内容是我阅读以上资料加上自己的理解所得,有部分摘抄自以上资料,侵删。
- 自定义Adapter与ListView
- listview与adapter用法
- listview与adapter用法
- listview与adapter用法
- listview与adapter用法
- adapter与listview
- listview与adapter用法
- listview与adapter用法
- ListView与Adapter笔记
- listview与adapter用法
- listview与adapter用法
- listview与adapter用法
- listview与adapter用法
- ListView与Adapter
- listview与adapter用法
- ListView与Adapter
- Listview与Adapter用法
- ListView与adapter用法
- 横线滚动条
- 郭霖老师androidpn教学视频笔记
- java并发系列——并发集合(一)
- 如何很好的使用SVN
- Android studio下使用ShareSDK
- ListView与Adapter
- JS网址正则验证
- Jenkins中使用ant管理Android应用开发生命周期
- css之inline-block
- android opencv 环境搭建
- 兔子问题
- Linux(CentOS) SVN服务器搭建+同步更新+多版本库+开机启动
- Jenkins入门系列之——02第二章 Jenkins安装与配置
- Android与服务器网站交互(一)