- 首先,说明一下,ListView中每一行包括以下三项:
- res/layout/main.xml
?
|
因为继承了ListActivity,所以ListView 的id设置为"@id/android:list"是必须的
- res/layout/lvitem.xml
注意:
在<?RelativeLayout>中
android:descendantFocusability=?"blocksDescendants"
和<?ImageButton>中
android:focusable?=?"false"
这两项的设置很关键,如果不设置,将导致ListView的ItemClick事件将无法触发,该事件被ImageButton的click事件屏蔽了。?
|
- 接下来,我们看看继承ListActivity的实现
在lvWithButtonExt中,为了能处理ImageButton的click事件,我继承了BaseAdapter类,并重新实现了getView()接口,在其中加入了Button的clicklistener,详见?lvButtonAdapter类的实现。
|
- 接下来,我们看看lvButtonAdapter?的实现
为了响应按钮的点击事件,首先要记录按钮的位置,然后为按钮设置clicklistener。
在重新实现的getView()接口中,我使用了lvButtonListener监听类,在构造函数中,记录行号,以便在OnClick接口中能准确的定位按钮所在的位置,进而对相应的行进行处理。
public?class?lvButtonAdapter?extends?BaseAdapter?{?
????private?class?buttonViewHolder?{?
????????ImageView?appIcon;?
????????TextView appName;?
????????ImageButton buttonClose;?
????}?
????
????private?ArrayList?<?HashMap?<?String?,?Object?>?>?mAppList;?
????private?LayoutInflater mInflater;?
????private?Context?mContext;?
????private?String?[?]?keyString;?
????private?int?[?]?valueViewID;?
????private?buttonViewHolder holder;?
????
????public?lvButtonAdapter(?Context?c,?ArrayList?<?HashMap?<?String?,?Object?>?>?appList,?intresource,?
????????????String?[?]?from?,?int?[?]?to)?{?
????????mAppList?=?appList;?
????????mContext?=?c;?
????????mInflater?=?(?LayoutInflater)?mContext.?getSystemService(?Context?.LAYOUT_INFLATER_SERVICE)?;?
????????keyString?=?new?String?[?from?.?length?]?;?
????????valueViewID?=?new?int?[?to.?length?]?;?
????????System?.?arraycopy?(?from?,?0,?keyString,?0,?from?.?length?)?;?
????????System?.?arraycopy?(?to,?0,?valueViewID,?0,?to.?length?)?;?
????}?
????
????@Override?
????public?int?getCount?(?)?{?
????????return?mAppList.?size?(?)?;?
????}?
????@Override?
????public?Object?getItem?(?int?position?)?{?
????????return?mAppList.?get?(?position?)?;?
????}?
????@Override?
????public?long?getItemId(?int?position?)?{?
????????return?position?;?
????}?
????public?void?removeItem?(?int?position?)?{?
????????mAppList.?remove?(?position?)?;?
????????this?.?notifyDataSetChanged(?)?;?
????}?
????
????@Override?
????public?View?getView?(?int?position?,?View?convertView,?ViewGroup?parent?)?{?
????????if?(?convertView?!?=?null?)?{?
????????????holder?=?(?buttonViewHolder)?convertView.?getTag?(?)?;?
????????}?else?{?
????????????convertView?=?mInflater.?inflate?(?R.?layout?.?lvitem,?null?)?;?
????????????holder?=?new?buttonViewHolder(?)?;?
????????????holder.?appIcon?=?(?ImageView?)?convertView.?findViewById(?valueViewID[?0]?)?;?
????????????holder.?appName?=?(?TextView)?convertView.?findViewById(?valueViewID[?1]?)?;?
????????????holder.?buttonClose?=?(?ImageButton)?convertView.?findViewById(?valueViewID[?2]?)?;?
????????????convertView.?setTag(?holder)?;?
????????}?
????????
????????HashMap?<?String?,?Object?>?appInfo?=?mAppList.?get?(?position?)?;?
????????if?(?appInfo?!?=?null?)?{?
????????????String?aname?=?(?String?)?appInfo.?get?(?keyString[?1]?)?;?
????????????int?mid?=?(?Integer?)?appInfo.?get?(?keyString[?0]?)?;?
????????????int?bid?=?(?Integer?)?appInfo.?get?(?keyString[?2]?)?;?
????????????holder.?appName.?setText?(?aname)?;?
????????????holder.?appIcon.?setImageDrawable(?holder.?appIcon.?getResources?(?)?.?getDrawable(mid)?)?;?
????????????holder.?buttonClose.?setImageDrawable(?holder.?buttonClose.?getResources?(?)?.getDrawable(?bid)?)?;?
????????????holder.?buttonClose.?setOnClickListener(?new?lvButtonListener(?position?)?)?;?
????????}?????????
????????return?convertView;?
????}?
????class?lvButtonListener?implements?OnClickListener?{?
????????private?int?position?;?
????????lvButtonListener(?int?pos)?{?
????????????position?=?pos;?
????????}?
????????
????????@Override?
????????public?void?onClick(?View?v)?{?
????????????int?vid=?v.?getId?(?)?;?
????????????if?(?vid?=?=?holder.?buttonClose.?getId?(?)?)?
????????????????removeItem?(?position?)?;?
????????}?
????}?
}
?
////////////////////////////////////////
备注1;?对于Android开发来说处理一些界面需要和Adapter适配器打交道,虽然Android自带了一些比如ArrayAdapter但是大多数情况下无法满足我们需要,所以就要从BaseAdapter派生一个类满足我们特殊的需要。
? 首先我们可能重写getView(),通过LayoutInflater的inflate方法映射一个自己定义的Layout布局xml加载或从xxxView中创建。这些大家可能滚瓜烂熟了但是仍然很多Android?开发者对于BaseAdapter中notifyDataSetChanged()方法不是很理解,notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容