如题,这里主要讲解SimpleAdapter的源码,ViewBinders只是作为该类的一个知识点。
说到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[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
?
"
<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的基本解析就到这里。
现在结合那篇文章说说剩下的一点(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设置监听事件。
本文详细解析了Android中SimpleAdapter的工作原理及其如何通过ViewBinders增强功能,特别是如何为ListView项设置监听事件。
2835

被折叠的 条评论
为什么被折叠?



