SimpleAdapter继承了BaseAdapter,作为一个Adapter的简单实现,SimpleAdapter支持的控件也比较少:checkable控件(例如checkbox,radioButton)、TextView和ImageView。

源码部分

源码路径:framework\base\core\java\android\widget\SimpleAdapter.java

package android.widget;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.view.LayoutInflater;import android.net.Uri;import java.util.ArrayList;import java.util.List;import java.util.Map;/**  * SimpleAdapter是一个将静态数据映射到在xml中定义的View上的简单的adapter。  * 开发者将数据保存在一个包含maps的ArrayList中。Arraylist中的每一项数据和view  * 中的每一个项对应。map中包含了view中每一行的数据。同样,开发者可以指定xml文件  * 来显示map中对应行的数据或者用map中的keys值来指定view。  *  * 数据的绑定发生在一下两种情况。  * 首先,如果{@link android.widget.SimpleAdapter.ViewBinder} 可见,  * {@link ViewBinder#setViewValue(android.view.View, Object, String)}被调用。  * 如果setViewValue返回true,那么则进行数据绑定。如果返回false,那么下面这些  * 情况将按顺序尝试执行  * 
    *
  • 如果View实现了Checkable(例如Checkbox),那么返回值将是boolean类型 *
  • TextView 返回值为String并且 {@link #setViewText(TextView, String)}将被调用 *
  • ImageView 返回值为资源id或者string,并且{@link #setViewImage(ImageView, int)} * 或者 {@link #setViewImage(ImageView, String)} 被调用 *
* 如果没有合适的binding返回,将会抛出 {@link IllegalStateException}异常 */ public class SimpleAdapter extends BaseAdapter implements Filterable { private int[] mTo; private String[] mFrom; private ViewBinder mViewBinder; private List<? extends Map> mData; private int mResource; private int mDropDownResource; private LayoutInflater mInflater; private SimpleFilter mFilter; private ArrayList> mUnfilteredData; /** * 构造函数 * * @param context SimpleAdapter运行的上下文 * @param data 包含map的list列表。列表中给的每一项和view中的每一个item对应。Maps中则包含View * 中每一行的所有数据,并且应该包含“from”中所有指定的项 * @param resource View中item的layout布局id,该view至少包含“to”中指定的项 * * @param from 一个将要被添加到map中的列名列表,和map中的每一个item对应 * @param to 需要显示view的id和“from”参数对应。必须全是TextView。 * */ public SimpleAdapter(Context context, List<? extends Map> data, int resource, String[] from, int[] to) { mData = data; mResource = mDropDownResource = resource; mFrom = from; mTo = to; mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } /** * @see android.widget.Adapter#getCount() */ public int getCount() { return mData.size(); } /** * @see android.widget.Adapter#getItem(int) */ public Object getItem(int position) { return mData.get(position); } /** * @see android.widget.Adapter#getItemId(int) */ public long getItemId(int position) { return position; } /** * getView直接调用createViewFromResource */ public View getView(int position, View convertView, ViewGroup parent) { return createViewFromResource(position, convertView, parent, mResource); } /** * greateViewFromResource进行了convertView的判断后,调用bindView来进行具体view的绑定 */ private View createViewFromResource(int position, View convertView, ViewGroup parent, int resource) { View v; if (convertView == null) { v = mInflater.inflate(resource, parent, false); } else { v = convertView; } bindView(position, v); return v; } /** * 设置用来创建drop down 视图的布局id * @param resource 定义了drop down 视图的资源文件 * @see #getDropDownView(int, android.view.View, android.view.ViewGroup) */ public void setDropDownViewResource(int resource) { this.mDropDownResource = resource; } /** * 同样调用createViewFromResource来生成对应的view */ @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { return createViewFromResource(position, convertView, parent, mDropDownResource); } /** * bindview应该是SimpleAdapter中核心的方法其中position为需要获取的view的位置,view为convertView */ private void bindView(int position, View view) { final Map dataSet = mData.get(position); if (dataSet == null) { return; } final ViewBinder binder = mViewBinder; final String[] from = mFrom; final int[] to = mTo; final int count = to.length; for (int i = 0; i < count; i++) { final View v = view.findViewById(to[i]); if (v != null) { final Object data = dataSet.get(from[i]); String text = data == null ? "" : data.toString(); if (text == null) { text = ""; } boolean bound = false; if (binder != null) { bound = binder.setViewValue(v, data, text); } if (!bound) { if (v instanceof Checkable) { if (data instanceof Boolean) { ((Checkable) v).setChecked((Boolean) data); } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else { throw new IllegalStateException(v.getClass().getName() + " should be bound to a Boolean, not a " + (data == null ? "" : data.getClass())); } } else if (v instanceof TextView) { // Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text); } else if (v instanceof ImageView) { if (data instanceof Integer) { setViewImage((ImageView) v, (Integer) data); } else { setViewImage((ImageView) v, text); } } else { throw new IllegalStateException(v.getClass().getName() + " is not a " + " view that can be bounds by this SimpleAdapter"); } } } } } /** * 返回一个ViewBinder */ public ViewBinder getViewBinder() { return mViewBinder; } /** * 设置ViewBinder */ public void setViewBinder(ViewBinder viewBinder) { mViewBinder = viewBinder; } /** * 该方法除被宾得View调用,用来给ImageView设置图片 * 如果ViewBinder不存在或者ViewBinder无法和ImageView绑定 */ public void setViewImage(ImageView v, int value) { v.setImageResource(value); } /** * 该方法被bindView调用,用来给ImageView设置图片 * 如果ViewBinder不存在或者ViewBinder无法和ImageView绑定 * * 默认情况下value被当作image资源,如果无法被当作image资源,那么将会被当作image uri */ public void setViewImage(ImageView v, String value) { try { v.setImageResource(Integer.parseInt(value)); } catch (NumberFormatException nfe) { v.setImageURI(Uri.parse(value)); } } /** * 该方法被bindView调用,用来给TextView色获知字符 * 如果ViewBinder不存在或者ViewBinder无法和TextView绑定 */ public void setViewText(TextView v, String text) { v.setText(text); } public Filter getFilter() { if (mFilter == null) { mFilter = new SimpleFilter(); } return mFilter; } /** * 这个内部静态接口被外部SimpleAdapter客户端用来修改views * 开发者通过实现这个接口,来修改view,如果这些View不能直接被SIM所支持, * 或者修改view绑定的方式 * @see SimpleAdapter#setViewImage(ImageView, int) * @see SimpleAdapter#setViewImage(ImageView, String) * @see SimpleAdapter#setViewText(TextView, String) */ public static interface ViewBinder { /** * 绑定指定的数据到指定的view上 * 如果binding被该方法处理,那么该方法必须返回true,如果返回false,那么SimpleAdapter * 将会自己处理binding过程 * @param view the view to bind the data to * @param data the data to bind to the view * @param textRepresentation a safe String representation of the supplied data: * it is either the result of data.toString() or an empty String but it * is never null * * @return true if the data was bound to the view, false otherwise */ boolean setViewValue(View view, Object data, String textRepresentation); } /** * 一个包含了某个前缀的数组过滤器,如果list中的每一项不包含该前缀,那么将会从该list中移除 */ private class SimpleFilter extends Filter { @Override protected FilterResults performFiltering(CharSequence prefix) { FilterResults results = new FilterResults(); if (mUnfilteredData == null) { mUnfilteredData = new ArrayList>(mData); } if (prefix == null || prefix.length() == 0) { ArrayList> list = mUnfilteredData; results.values = list; results.count = list.size(); } else { String prefixString = prefix.toString().toLowerCase(); ArrayList> unfilteredValues = mUnfilteredData; int count = unfilteredValues.size(); ArrayList> newValues = new ArrayList>(count); for (int i = 0; i < count; i++) { Map h = unfilteredValues.get(i); if (h != null) { int len = mTo.length; for (int j=0; j>) results.values; if (results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }}

事例部分

list_item.xml

<?xml version="1.0" encoding="utf-8"?>                            

SimpleAdapter中包含了一个Interface ViewBinder,这里分两种情况,分别介绍两个事例,第一个,不使用ViewBinder;第二个,使用ViewBinder

SimpleAdapterNoBinder.java

package com.lj.simpleadaptertest;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Random;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;import android.widget.SimpleAdapter;public class SimpleAdapterNoBinder extends Activity {ListView mListView;List> mData = new ArrayList>();public static final String KEY_IMG = "imgage";public static final String KEY_TITLE = "title";public static final String KEY_SUMMARY = "summary";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_no_binder);mListView = (ListView) findViewById(R.id.list_no_binder);               //定义一个mAdapter,设置自定义的layout布局,调用getData返回需要显示的数据SimpleAdapter mAdapter = new SimpleAdapter(this, getData(),R.layout.list_item, new String[] { KEY_IMG, KEY_TITLE,KEY_SUMMARY, }, new int[] { R.id.image, R.id.title,R.id.summary });mListView.setAdapter(mAdapter);}       //map中包含三部分数据,ImageView设置为默认的R.drawable.ic_launcher,两个TextView设置为随机的字符private List> getData() {List> list = new ArrayList>();Map map;for (int i = 0; i < 30; i++) {map = new HashMap();map.put(KEY_IMG, R.drawable.ic_launcher);map.put(KEY_TITLE, getTitleText(8));map.put(KEY_SUMMARY, getTitleText(10));list.add(map);}return list;}private Object getTitleText(int length) {String mString = "qwertyuiopasdfghjklzxcvbnm";Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(mString.length());sb.append(mString.charAt(number));}return sb.toString();}}
SimpleAdapterWithBinder.java

package com.lj.simpleadaptertest;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Random;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Color;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.ImageView;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.TextView;public class SimpleAdapterWithBinder extends Activity {ListView mListView;List> mData = new ArrayList>();public static final String KEY_IMG = "imgage";public static final String KEY_TITLE = "title";public static final String KEY_SUMMARY = "summary";public static final String KEY_CHECK = "check";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_no_binder);mListView = (ListView) findViewById(R.id.list_no_binder);SimpleAdapter mAdapter = new SimpleAdapter(this, getData(),R.layout.list_item, new String[] { KEY_IMG, KEY_TITLE,KEY_SUMMARY, }, new int[] { R.id.image, R.id.title,R.id.summary });mAdapter.setViewBinder(new TestViewBinder());mListView.setAdapter(mAdapter);}private List> getData() {List> list = new ArrayList>();Map map;for (int i = 0; i < 30; i++) {map = new HashMap();map.put(KEY_IMG, R.drawable.ic_launcher);map.put(KEY_TITLE, getTitleText(8));map.put(KEY_SUMMARY, getTitleText(10));map.put(KEY_CHECK, (i / 2 == 0 ? true : false));list.add(map);}return list;}private Object getTitleText(int length) {String mString = "qwertyuiopasdfghjklzxcvbnm";Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(mString.length());sb.append(mString.charAt(number));}return sb.toString();}public Bitmap getBitmap(final String url) {Log.e("lijian", "url = " + url);Bitmap bmp = null;try {URL mUrl = new URL(url);HttpURLConnection conn = (HttpURLConnection) mUrl.openConnection();InputStream is = conn.getInputStream();bmp = BitmapFactory.decodeStream(is);} catch (Exception e) {e.printStackTrace();}return bmp;}/** * 实现ViewBinder接口 *  */class TestViewBinder implements SimpleAdapter.ViewBinder {@Overridepublic boolean setViewValue(View view, Object data,String textRepresentation) {if ((view instanceof ImageView)) {Log.e("lijian", "set internet image data " + data);ImageView mImageView = (ImageView) view;mImageView.setImageResource(R.drawable.error);return true;} else if (view instanceof TextView && view.getId() ==R.id.summary) {TextView mTextView = (TextView) view;mTextView.setText("你好");return true;}return false;}}}

效果图:

Android之Adapter系列之SimpleAdapter类_第1张图片

 图 1

Android之Adapter系列之SimpleAdapter类_第2张图片

图二

事例总结

图片以和图片二分别代表不使用ViewBinder和使用ViewBinder的结果,每一个Item的图片和summary字符可以在ViewBinder实现的类中的setViewValue中修改。

源码下载

更多相关文章

  1. Java乔晓松-android的四大组件之一Service(服务的绑定)
  2. android之网络请求 -- 获取RecyclerView的列表项(图片 + 文字)
  3. Android系列之Post图片和数据
  4. Android查询短信数据库
  5. Android应用程序的Java数据更新和UI同步改变
  6. android 开发之activity之间传递数据
  7. Android之Activity之间的数据通信方式大全(二)
  8. Android——横竖屏切换以及数据保存
  9. Android数据存取之Preferences

随机推荐

  1. Esys Demo
  2. CSS伪类选择器和CSS盒模型常用属性
  3. 伪类选择器的应用/盒模型的分析
  4. 【Linux学习】OpenCV+ROS 实现人脸识别(Ub
  5. 常用的两种伪类选择器
  6. 伪类和伪元素和盒模型
  7. Ubuntu软件更新更换源
  8. CSS常用伪类选择器的总结与盒子模型的简
  9. 0707伪类选择器/盒模型
  10. html基础:css伪类选择器的使用和盒模型的