一直没认真看过android的源码,也不太敢看,稀里糊涂也敲了一年的代码,现在想好好学习了,就把常用的源码都看了一下,小伙伴们来涨姿势吧,有错误的地方,直接指出,我脸厚不怕丢人。来吧。

刚开始学android的时候我经常使用SimpleAdapter,但是后来经常用到的对象实体,SimpleAdapter也就不符合要求了,一直自己继承BaseAdapter,但是有的地方用SimpleAdapter还是比较方便的,一句话就搞定了,也不用写Adapter,所以来悄悄源码吧。
SimpleAdapter的初始化:

   
SimpleAdapter sAdapter=new SimpleAdapter(this, mList, R.layout.activity_main,new String[]{"name","pwd"},new int[]{R.id.tv_name,R.id.tv_pwd});
   
下面是android的源码,加了详细的注释,不用再多说:
public class SimpleAdapter extends BaseAdapter implements Filterable {private int[] mTo; // 指向布局里面控件的id 比如:R.id.btnprivate String[] mFrom; // 数据来源,来自Map里面的keyprivate ViewBinder mViewBinder;// 接口类型,里面有个setViewValue方法,用于出现特殊类型控件比如:drawable的时候在外部初始化接口,实现具体方法private List<? extends Map<String, ?>> mData;// 用List打包的Map数据源private int mResource;// 布局private int mDropDownResource;// 不知道干嘛用的,但是估计也是留给外部调用的private LayoutInflater mInflater;// 这个大家都知道,LayoutInflater用来载入界面private SimpleFilter mFilter;// 过滤器,一般用不到private ArrayList<Map<String, ?>> mUnfilteredData;// SimpleAdapter初始化,将传进了的参数都赋给本地的对应变量public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,int resource, String[] from, int[] to) {mData = data;mResource = mDropDownResource = resource;mFrom = from;mTo = to;mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);}/* * ListView 针对每个item,要求 adapter “返回一个视图” (getView), * 也就是说ListView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到ListView的长度, * 然后根据这个长度,调用getView()一行一行的绘制ListView的每一项。如果你的getCount()返回值是0的话, * 列表一行都不会显示,如果返回1,就只显示一行。返回几则显示几行。如果我们有几千几万甚至更多的item要显示怎么办? * 为每个Item创建一个新的View?不可能!!!实际上Android早已经缓存了这些视图,大家可以看下下面这个截图来理解下, * 这个图是解释ListView工作原理的最经典的图了大家可以收藏下,不懂的时候拿来看看,加深理解, * 其实Android中有个叫做Recycler的构件 */public int getCount() {return mData.size();}public Object getItem(int position) {return mData.get(position);}public long getItemId(int position) {return position;}public View getView(int position, View convertView, ViewGroup parent) {// 调用createViewFromResource来优化内存return createViewFromResource(position, convertView, parent, mResource);}/* * ListView的机制在这里再说一下,当第一个数据来getView的时候convertView肯定是null, * 那么就用mInflater.inflate(resource, parent, * false)给它初始化一个View,但是当一屏滑到底了,第一个item,滑出了屏幕,那么它将 * 从底部出来,那时候convertView就不为null,这个方法的好处就是当convertView不为null * 的时候不用加载布局,直接使用convertView, 节省了一步,这也是所说的优化ListView的第一个步骤。 */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;}public void setDropDownViewResource(int resource) {this.mDropDownResource = resource;}@Overridepublic View getDropDownView(int position, View convertView, ViewGroup parent) {return createViewFromResource(position, convertView, parent,mDropDownResource);}// 这个方法的主要功能就是按照 to数组里面控件的顺序挨个赋值,比如new int[]{R.id.tv_name,R.id.tv_pwd}。private void bindView(int position, View view) {final Map dataSet = mData.get(position);// 找到对应的position位置的map数据// 如果没找到跳出if (dataSet == null) {return;}/* * 将外部实现的ViewBinder,赋值给本地,SimpleAdapter能够实现: * checkBox,CheckedTextView,TextView * ,ImageView,数据类型也就是Boolean,Integer,Stirng, 所以特殊数据类型的时候才用到ViewBinder * ,如果没用到就不需要外部实现ViewBinder接口和里面的方法 */final ViewBinder binder = mViewBinder;final String[] from = mFrom;final int[] to = mTo;final int count = to.length;//view.findViewById(to[i]),循环找控件for (int i = 0; i < count; i++) {final View v = view.findViewById(to[i]);//如果v不为空的话,找到对应的数据,Object类型的data转换为String,因为boolean在map里面纯的也是true或者falseif (v != null) {final Object data = dataSet.get(from[i]);String text = data == null ? "" : data.toString();if (text == null) {text = "";}//标志变量bound,判断外部有没有实现ViewBinder,如果实现了,就执行binder.setViewValue(v, data, text),如果符合特殊条件,就返回trueboolean bound = false;if (binder != null) {bound = binder.setViewValue(v, data, text);}//如果满足if (!bound)那么bound就还是false,说明是普通数据if (!bound) {//查看v是不是Checkable的实例化类型,满足的情况可能是CheckBox,CheckedTextViewif (v instanceof Checkable) {//如果数据类型是boolean,那么就是CheckBoxif (data instanceof Boolean) {((Checkable) v).setChecked((Boolean) data);//如果不是CheckBox,那么判断是不是继承TextView的CheckedTextView,是的话赋值,不是就抛出异常} else if (v instanceof TextView) {setViewText((TextView) v, text);} else {throw new IllegalStateException(v.getClass().getName()+ " should be bound to a Boolean, not a "+ (data == null ? "<unknown type>": data.getClass()));}//如果不是Checkable的实例化类型,判断是不是TextView的实例化类型} else if (v instanceof TextView) {setViewText((TextView) v, text);//都不是以上情况,就判断一下是不是ImageView的实例化类型} else if (v instanceof ImageView) {//这里只满足数据类型为int也就是R.drawable.ic,和String类型的url,如果想实现直接用drawbale,就要实现ViewBinderif (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");}}}}}public ViewBinder getViewBinder() {return mViewBinder;}public void setViewBinder(ViewBinder viewBinder) {mViewBinder = viewBinder;}public void setViewImage(ImageView v, int value) {v.setImageResource(value);}public void setViewImage(ImageView v, String value) {try {v.setImageResource(Integer.parseInt(value));} catch (NumberFormatException nfe) {v.setImageURI(Uri.parse(value));}}public void setViewText(TextView v, String text) {v.setText(text);}public Filter getFilter() {if (mFilter == null) {mFilter = new SimpleFilter();}return mFilter;}public static interface ViewBinder {boolean setViewValue(View view, Object data, String textRepresentation);}//这个不知道干嘛用的,也没用过,好像是过滤数据的private class SimpleFilter extends Filter {@Overrideprotected FilterResults performFiltering(CharSequence prefix) {FilterResults results = new FilterResults();if (mUnfilteredData == null) {mUnfilteredData = new ArrayList<Map<String, ?>>(mData);}if (prefix == null || prefix.length() == 0) {ArrayList<Map<String, ?>> list = mUnfilteredData;results.values = list;results.count = list.size();} else {String prefixString = prefix.toString().toLowerCase();ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData;int count = unfilteredValues.size();ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(count);for (int i = 0; i < count; i++) {Map<String, ?> h = unfilteredValues.get(i);if (h != null) {int len = mTo.length;for (int j = 0; j < len; j++) {String str = (String) h.get(mFrom[j]);String[] words = str.split(" ");int wordCount = words.length;for (int k = 0; k < wordCount; k++) {String word = words[k];if (word.toLowerCase().startsWith(prefixString)) {newValues.add(h);break;}}}}}results.values = newValues;results.count = newValues.size();}return results;}@Overrideprotected void publishResults(CharSequence constraint,FilterResults results) {// noinspection uncheckedmData = (List<Map<String, ?>>) results.values;if (results.count > 0) {notifyDataSetChanged();} else {notifyDataSetInvalidated();}}}}


最近在公司涨了很多姿势,大部分是Java的继承,接口,多态,抽象这些学过但是理解很肤浅的东西,以前自己写软件没什么规范,也没怎么去抽象,所以代码很不上档次,老鸟看到我的代码就笑话我,现在我准备好好学一下,希望自己有一天也能写出很正规的代码。
   


更多相关文章

  1. android 数据存储之 读写文件
  2. Android中Parcelable接口对比Serializable
  3. Android(安卓)sqlite本地数据库
  4. android 实现listview动态加载列表项www.maiziedu.com
  5. Android实现动态向Gallery中添加图片及倒影与3D效果示例
  6. Android(安卓)网络管家ConnectivityManager
  7. Android(安卓)Gson
  8. DataBinding 的简单使用
  9. Android(安卓)事件分发源码分析

随机推荐

  1. 笔记 TextView类:
  2. 升级代码的大概设计
  3. [安卓]Android导入第三方静态库.a编译成
  4. 更新Android Studio版本出现Could not fi
  5. Android系统(245)---SystemServer进程的创
  6. Android 照相机
  7. Android视频播放项目总结之 使用第三方Vi
  8. android 发送邮件--实现 send email for
  9. Android之——自己定义TextView
  10. SharePreferences源码分析(SharedPreferen