您的位置:首页 > 其它

关于ListView (2)——SimpleAdapter源码解析与ViewBinders的用法

2012-03-13 15:06 447 查看
如题,这里主要讲解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设置监听事件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: