Android SimpleAdapter源码详解

来源:互联网 发布:sql replace into用法 编辑:程序博客网 时间:2024/06/05 20:36


</pre><span style="font-family: Arial; font-size: 14px; line-height: 26px;">SimpleAdapter的初始化:</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">SimpleAdapter sAdapter=</span><span class="keyword" style="margin: 0px; padding: 0px; border: none; color: blue; font-weight: bold; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">new</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;"> SimpleAdapter(</span><span class="keyword" style="margin: 0px; padding: 0px; border: none; color: blue; font-weight: bold; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">this</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">, mList, R.layout.activity_main,</span><span class="keyword" style="margin: 0px; padding: 0px; border: none; color: blue; font-weight: bold; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">new</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;"> String[]{</span><span class="string" style="margin: 0px; padding: 0px; border: none; color: red; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">"name"</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">,</span><span class="string" style="margin: 0px; padding: 0px; border: none; color: red; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">"pwd"</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">},</span><span class="keyword" style="margin: 0px; padding: 0px; border: none; color: blue; font-weight: bold; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">new</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;"> </span><span class="keyword" style="margin: 0px; padding: 0px; border: none; color: blue; font-weight: bold; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">int</span><span style="margin: 0px; padding: 0px; border: none; font-family: Consolas, 'Courier New', Courier, mono, serif; line-height: 18px;">[]{R.id.tv_name,R.id.tv_pwd});</span></p><p><pre name="code" class="html">
SimpleAdapter代码

  1. public class SimpleAdapter extends BaseAdapter implements Filterable {  
  2.     private int[] mTo; // 指向布局里面控件的id 比如:R.id.btn  
  3.     private String[] mFrom; // 数据来源,来自Map里面的key  
  4.     private ViewBinder mViewBinder;// 接口类型,里面有个setViewValue方法,用于出现特殊类型控件比如:drawable的时候在外部初始化接口,实现具体方法  
  5.   
  6.     private List<? extends Map<String, ?>> mData;// 用List打包的Map数据源  
  7.   
  8.     private int mResource;// 布局  
  9.     private int mDropDownResource;// 不知道干嘛用的,但是估计也是留给外部调用的  
  10.     private LayoutInflater mInflater;// 这个大家都知道,LayoutInflater用来载入界面  
  11.   
  12.     private SimpleFilter mFilter;// 过滤器,一般用不到  
  13.     private ArrayList<Map<String, ?>> mUnfilteredData;  
  14.   
  15.     // SimpleAdapter初始化,将传进了的参数都赋给本地的对应变量  
  16.     public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,  
  17.             int resource, String[] from, int[] to) {  
  18.         mData = data;  
  19.         mResource = mDropDownResource = resource;  
  20.         mFrom = from;  
  21.         mTo = to;  
  22.         mInflater = (LayoutInflater) context  
  23.                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
  24.     }  
  25.   
  26.     /* 
  27.      * ListView 针对每个item,要求 adapter “返回一个视图” (getView), 
  28.      * 也就是说ListView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到ListView的长度, 
  29.      * 然后根据这个长度,调用getView()一行一行的绘制ListView的每一项。如果你的getCount()返回值是0的话, 
  30.      * 列表一行都不会显示,如果返回1,就只显示一行。返回几则显示几行。如果我们有几千几万甚至更多的item要显示怎么办? 
  31.      * 为每个Item创建一个新的View?不可能!!!实际上Android早已经缓存了这些视图,大家可以看下下面这个截图来理解下, 
  32.      * 这个图是解释ListView工作原理的最经典的图了大家可以收藏下,不懂的时候拿来看看,加深理解, 
  33.      * 其实Android中有个叫做Recycler的构件 
  34.      */  
  35.     public int getCount() {  
  36.         return mData.size();  
  37.     }  
  38.   
  39.     public Object getItem(int position) {  
  40.         return mData.get(position);  
  41.     }  
  42.   
  43.     public long getItemId(int position) {  
  44.         return position;  
  45.     }  
  46.   
  47.     public View getView(int position, View convertView, ViewGroup parent) {  
  48.         // 调用createViewFromResource来优化内存  
  49.         return createViewFromResource(position, convertView, parent, mResource);  
  50.     }  
  51.   
  52.     /* 
  53.      * ListView的机制在这里再说一下,当第一个数据来getView的时候convertView肯定是null, 
  54.      * 那么就用mInflater.inflate(resource, parent, 
  55.      * false)给它初始化一个View,但是当一屏滑到底了,第一个item,滑出了屏幕,那么它将 
  56.      * 从底部出来,那时候convertView就不为null,这个方法的好处就是当convertView不为null 
  57.      * 的时候不用加载布局,直接使用convertView, 节省了一步,这也是所说的优化ListView的第一个步骤。 
  58.      */  
  59.     private View createViewFromResource(int position, View convertView,  
  60.             ViewGroup parent, int resource) {  
  61.         View v;  
  62.         if (convertView == null) {  
  63.             v = mInflater.inflate(resource, parent, false);  
  64.         } else {  
  65.             v = convertView;  
  66.         }  
  67.         // 这个方法是核心  
  68.         bindView(position, v);  
  69.   
  70.         return v;  
  71.     }  
  72.   
  73.     public void setDropDownViewResource(int resource) {  
  74.         this.mDropDownResource = resource;  
  75.     }  
  76.   
  77.     @Override  
  78.     public View getDropDownView(int position, View convertView, ViewGroup parent) {  
  79.         return createViewFromResource(position, convertView, parent,  
  80.                 mDropDownResource);  
  81.     }  
  82.   
  83.     // 这个方法的主要功能就是按照 to数组里面控件的顺序挨个赋值,比如new int[]{R.id.tv_name,R.id.tv_pwd}。  
  84.     private void bindView(int position, View view) {  
  85.         final Map dataSet = mData.get(position);// 找到对应的position位置的map数据  
  86.         // 如果没找到跳出  
  87.         if (dataSet == null) {  
  88.             return;  
  89.         }  
  90.         /* 
  91.          * 将外部实现的ViewBinder,赋值给本地,SimpleAdapter能够实现: 
  92.          * checkBox,CheckedTextView,TextView 
  93.          * ,ImageView,数据类型也就是Boolean,Integer,Stirng, 所以特殊数据类型的时候才用到ViewBinder 
  94.          * ,如果没用到就不需要外部实现ViewBinder接口和里面的方法 
  95.          */  
  96.         final ViewBinder binder = mViewBinder;  
  97.         final String[] from = mFrom;  
  98.         final int[] to = mTo;  
  99.         final int count = to.length;  
  100. //view.findViewById(to[i]),循环找控件  
  101.         for (int i = 0; i < count; i++) {  
  102.             final View v = view.findViewById(to[i]);  
  103.             //如果v不为空的话,找到对应的数据,Object类型的data转换为String,因为boolean在map里面纯的也是true或者false  
  104.             if (v != null) {  
  105.                 final Object data = dataSet.get(from[i]);  
  106.                 String text = data == null ? "" : data.toString();  
  107.                 if (text == null) {  
  108.                     text = "";  
  109.                 }  
  110. //标志变量bound,判断外部有没有实现ViewBinder,如果实现了,就执行binder.setViewValue(v, data, text),如果符合特殊条件,就返回true  
  111.                 boolean bound = false;  
  112.                 if (binder != null) {  
  113.                     bound = binder.setViewValue(v, data, text);  
  114.                 }  
  115. //如果满足if (!bound)那么bound就还是false,说明是普通数据  
  116.                 if (!bound) {  
  117.                     //查看v是不是Checkable的实例化类型,满足的情况可能是CheckBox,CheckedTextView  
  118.                     if (v instanceof Checkable) {  
  119.                         //如果数据类型是boolean,那么就是CheckBox  
  120.                         if (data instanceof Boolean) {  
  121.                             ((Checkable) v).setChecked((Boolean) data);  
  122.                             //如果不是CheckBox,那么判断是不是继承TextView的CheckedTextView,是的话赋值,不是就抛出异常  
  123.                         } else if (v instanceof TextView) {  
  124.                             setViewText((TextView) v, text);  
  125.                         } else {  
  126.                             throw new IllegalStateException(v.getClass()  
  127.                                     .getName()  
  128.                                     + " should be bound to a Boolean, not a "  
  129.                                     + (data == null ? "<unknown type>"  
  130.                                             : data.getClass()));  
  131.                         }  
  132.                         //如果不是Checkable的实例化类型,判断是不是TextView的实例化类型  
  133.                     } else if (v instanceof TextView) {  
  134.                         setViewText((TextView) v, text);  
  135.                         //都不是以上情况,就判断一下是不是ImageView的实例化类型  
  136.                     } else if (v instanceof ImageView) {  
  137.                         //这里只满足数据类型为int也就是R.drawable.ic,和String类型的url,如果想实现直接用drawbale,就要实现ViewBinder  
  138.                         if (data instanceof Integer) {  
  139.                             setViewImage((ImageView) v, (Integer) data);  
  140.                         } else {  
  141.                             setViewImage((ImageView) v, text);  
  142.                         }  
  143.                     } else {  
  144.                         throw new IllegalStateException(  
  145.                                 v.getClass().getName()  
  146.                                         + " is not a "  
  147.                                         + " view that can be bounds by this SimpleAdapter");  
  148.                     }  
  149.                 }  
  150.             }  
  151.         }  
  152.     }  
  153.   
  154.     public ViewBinder getViewBinder() {  
  155.         return mViewBinder;  
  156.     }  
  157.   
  158.     public void setViewBinder(ViewBinder viewBinder) {  
  159.         mViewBinder = viewBinder;  
  160.     }  
  161.   
  162.     public void setViewImage(ImageView v, int value) {  
  163.         v.setImageResource(value);  
  164.     }  
  165.   
  166.     public void setViewImage(ImageView v, String value) {  
  167.         try {  
  168.             v.setImageResource(Integer.parseInt(value));  
  169.         } catch (NumberFormatException nfe) {  
  170.             v.setImageURI(Uri.parse(value));  
  171.         }  
  172.     }  
  173.   
  174.     public void setViewText(TextView v, String text) {  
  175.         v.setText(text);  
  176.     }  
  177.   
  178.     public Filter getFilter() {  
  179.         if (mFilter == null) {  
  180.             mFilter = new SimpleFilter();  
  181.         }  
  182.         return mFilter;  
  183.     }  
  184.   
  185.     public static interface ViewBinder {  
  186.         boolean setViewValue(View view, Object data, String textRepresentation);  
  187.     }  
  188. //这个不知道干嘛用的,也没用过,好像是过滤数据的  
  189.     private class SimpleFilter extends Filter {  
  190.   
  191.         @Override  
  192.         protected FilterResults performFiltering(CharSequence prefix) {  
  193.             FilterResults results = new FilterResults();  
  194.   
  195.             if (mUnfilteredData == null) {  
  196.                 mUnfilteredData = new ArrayList<Map<String, ?>>(mData);  
  197.             }  
  198.   
  199.             if (prefix == null || prefix.length() == 0) {  
  200.                 ArrayList<Map<String, ?>> list = mUnfilteredData;  
  201.                 results.values = list;  
  202.                 results.count = list.size();  
  203.             } else {  
  204.                 String prefixString = prefix.toString().toLowerCase();  
  205.   
  206.                 ArrayList<Map<String, ?>> unfilteredValues = mUnfilteredData;  
  207.                 int count = unfilteredValues.size();  
  208.   
  209.                 ArrayList<Map<String, ?>> newValues = new ArrayList<Map<String, ?>>(  
  210.                         count);  
  211.   
  212.                 for (int i = 0; i < count; i++) {  
  213.                     Map<String, ?> h = unfilteredValues.get(i);  
  214.                     if (h != null) {  
  215.   
  216.                         int len = mTo.length;  
  217.   
  218.                         for (int j = 0; j < len; j++) {  
  219.                             String str = (String) h.get(mFrom[j]);  
  220.   
  221.                             String[] words = str.split(" ");  
  222.                             int wordCount = words.length;  
  223.   
  224.                             for (int k = 0; k < wordCount; k++) {  
  225.                                 String word = words[k];  
  226.   
  227.                                 if (word.toLowerCase().startsWith(prefixString)) {  
  228.                                     newValues.add(h);  
  229.                                     break;  
  230.                                 }  
  231.                             }  
  232.                         }  
  233.                     }  
  234.                 }  
  235.   
  236.                 results.values = newValues;  
  237.                 results.count = newValues.size();  
  238.             }  
  239.   
  240.             return results;  
  241.         }  
  242.   
  243.         @Override  
  244.         protected void publishResults(CharSequence constraint,  
  245.                 FilterResults results) {  
  246.             // noinspection unchecked  
  247.             mData = (List<Map<String, ?>>) results.values;  
  248.             if (results.count > 0) {  
  249.                 notifyDataSetChanged();  
  250.             } else {  
  251.                 notifyDataSetInvalidated();  
  252.             }  
  253.         }  
  254.     }  
  255. }

转载自 http://blog.csdn.net/mobilexu/article/details/9850555

0 0
原创粉丝点击