关于ListView (2)——SimpleAdapter源码解析与ViewBinders的用法
2011-05-03 21:36
841 查看
如题,这里主要讲解SimpleAdapter的源码,ViewBinders只是作为该类的一个知识点。
说到android源码,很多人看下去可能会开始觉得头越来越晕,最后就不了了之。不过理解源码确实能让自己更深入的了解android的运作,更顺手的写出优秀的代码。其实看android源码,一开始不一定就立即从重要或者核心开始下手,即使能够看下去,也会很累,浪费的时间也多。就如解剖一只牛,让我来,我就会先一刀一刀去掉外层的肉(因为我不是那种经验丰富的人),先从简单的,一层一层剥开,牛肉慢慢的去掉,开始可以看到整个骨架了。这样既不会很快失去耐心,又能挑起自己继续学习下去的欲望,虽然这种方法是很慢的,但是过程明白了,以后就可以快。当然剩下的骨头也不容易啃 :),不过至少轻松很多。
这里讲解的例子主要是跟别人的结合在一起说,引用的文章链接:http://mgmblog.com/2008/12/29/simpleadapter-viewbinders/
new SimpleAdapter(
this,
_activityNames,
R.layout.row,
new String[] { ACTIVITY_NAME_ENTRY },
new int[] { R.id.text1 } );
这是创建SimpleAdapter的一段代码,先不要理那些变量。当运行这段代码时,会有如下操作:
SimpleAdapter下面的源码跟继承重写BaseAdapter里面的方法差不多。
// bindView是重点,主要是将你前面传入给item的xml文件解析,然后判断是Checkable还是TextView或者是ImageView,做出相应的处理。
这段代码主要是针对特殊数据做处理
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
SimpleAdapter的基本解析就到这里。
现在结合那篇文章说说剩下的一点([i]ViewBinders)。
重写TextView,触发按键会跳转到另一个intent
ArrayList<HashMap<String, ToolboxRow>> _activityNames;
////添加name和intent到数据源_activityNames
////// ToolBinder,这里将重写ViewBinder里面的方法setViewValue,给textview设置onclick事件。这里其实跟重写BaseAapter的做法差不多,都是一样的设置事件。
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
说到android源码,很多人看下去可能会开始觉得头越来越晕,最后就不了了之。不过理解源码确实能让自己更深入的了解android的运作,更顺手的写出优秀的代码。其实看android源码,一开始不一定就立即从重要或者核心开始下手,即使能够看下去,也会很累,浪费的时间也多。就如解剖一只牛,让我来,我就会先一刀一刀去掉外层的肉(因为我不是那种经验丰富的人),先从简单的,一层一层剥开,牛肉慢慢的去掉,开始可以看到整个骨架了。这样既不会很快失去耐心,又能挑起自己继续学习下去的欲望,虽然这种方法是很慢的,但是过程明白了,以后就可以快。当然剩下的骨头也不容易啃 :),不过至少轻松很多。
这里讲解的例子主要是跟别人的结合在一起说,引用的文章链接:http://mgmblog.com/2008/12/29/simpleadapter-viewbinders/
SimpleAdapter toolsAdapter =
new SimpleAdapter(
this,
_activityNames,
R.layout.row,
new String[] { ACTIVITY_NAME_ENTRY },
new int[] { R.id.text1 } );
这是创建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); }
SimpleAdapter下面的源码跟继承重写BaseAdapter里面的方法差不多。
/** * @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; } /** * @see android.widget.Adapter#getView(int, View, ViewGroup) */ public View getView(int position, View convertView, ViewGroup parent) { return createViewFromResource(position, convertView, parent, mResource); } //这里提高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; }
// bindView是重点,主要是将你前面传入给item的xml文件解析,然后判断是Checkable还是TextView或者是ImageView,做出相应的处理。
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); 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 ? "<unknown type>" : 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"); } } } } }
这段代码主要是针对特殊数据做处理
boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
SimpleAdapter的基本解析就到这里。
现在结合那篇文章说说剩下的一点([i]ViewBinders)。
重写TextView,触发按键会跳转到另一个intent
/////ToolNameView.java public class ToolNameView extends TextView { private Intent _intentToLaunch; public ToolNameView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); setupView(); } public ToolNameView(Context context, AttributeSet attrs) { super(context, attrs); setupView(); } public ToolNameView(Context context) { super(context); setupView(); } private void setupView() { this.setOnClickListener( new OnClickListener() { public void onClick(View v) { getContext().startActivity( _intentToLaunch ); } }); } public void setIntentToLaunch( Intent intent ) { _intentToLaunch = intent; } } ///// layout/row.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/vw1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <com.mgm.android.toolbox.ToolNameView android:id="@+id/text1" android:textSize="16sp" android:textStyle="bold" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="3dip"/> </LinearLayout> //////类 class ToolboxRow { private Intent _intentToLaunch; private String _name; public ToolboxRow( Intent intentToLaunch, String name ) { _intentToLaunch = intentToLaunch; _name = name; } public Intent getIntentToLaunch() { return _intentToLaunch; } public String getName() { return _name; } }
ArrayList<HashMap<String, ToolboxRow>> _activityNames;
////添加name和intent到数据源_activityNames
/** * DON'T FORGET TO ALSO ADD ACTIVITY TO MANIFEST!! * * @param name * @param intentToLaunch */ private void addActivityToList( String name, Intent intentToLaunch ) { HashMap entry = new HashMap(); ToolboxRow row = new ToolboxRow( intentToLaunch, name ); entry.put( ACTIVITY_NAME_ENTRY, row ); _activityNames.add( entry ); }
////// ToolBinder,这里将重写ViewBinder里面的方法setViewValue,给textview设置onclick事件。这里其实跟重写BaseAapter的做法差不多,都是一样的设置事件。
class ToolBinder implements ViewBinder { public boolean setViewValue(View view, Object data, String textRepresentation) { ToolNameView tool = (ToolNameView)view; ToolboxRow row = (ToolboxRow)data; tool.setIntentToLaunch( row.getIntentToLaunch() ); tool.setText( row.getName() ); return true; } } 主要代码: public class Toolbox extends ListActivity { private static final String ACTIVITY_NAME_ENTRY = "activity_name"; ArrayList<HashMap<String, ToolboxRow>> _activityNames; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // define the list which holds the information of the list _activityNames = new ArrayList<HashMap<String, ToolboxRow>>(); addActivityToList( "Data Roaming", new Intent( this, DataRoamingSetting.class ) ); addActivityToList( "Expanding Example", new Intent( this, Expando.class ) ); SimpleAdapter toolsAdapter = new SimpleAdapter( this, _activityNames, R.layout.row, new String[] { ACTIVITY_NAME_ENTRY }, new int[] { R.id.text1 } ); toolsAdapter.setViewBinder( new ToolBinder() ); setListAdapter( toolsAdapter ); } }
toolsAdapter.setViewBinder( new ToolBinder() );
这里给SimpleAdapter设置setViewBinder方法,当执行到
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}
会去里面执行,返回true。这样就是完成给item设置监听事件。
相关文章推荐
- 关于ListView (2)——SimpleAdapter源码解析与ViewBinders的用法
- 关于ListView (2)——SimpleAdapter源码解析与ViewBinders的用法
- 关于ListView (2)——SimpleAdapter源码解析与ViewBinders的用法
- Android自定义View(二)---拉刷新ListView 下之事件分发源码解析
- 关于Listview、Girdview的setSelection无效的解决方法与解析
- CircleImageView用法及源码解析(雷惊风)
- RecyclerView 的常用方法;工作原理与ListView比较;源码解析
- 关于ImageView的源码简单解析
- GuidePageView的用法及源码解析
- 源码分析-ListView组件addHeaderView()方法的源码解析
- ImageLoader源码解析(五) 补充 针对ListView或者RecycleView的优化
- TagView的用法及源码解析
- 关于ListView使用ConvertView和ViewHolder实现性能优化
- Log4net源码View之Logger解析
- 源码解析之setContentView
- 关于boost::any源码的额外解析
- springMVC的源码解析——关于自定义元素解析
- Android View 事件分发机制 源码解析 (上)
- 源码解析Android中View的layout布局过程
- 关于MatConvNet的反向传播原理及源码解析