listView中如何加入button或者ImageView

第一个问题:                                                                

 今天做listView困惑了好久,开始一直是不能点击,只能显示,发现:

convertView = LayoutInflater.from(context).inflate(R.layout.setting_net1, null);

原来我setting_net1用了ScrollLayout,肯定是不行的了,所以用LinearLayout。

 第二个问题:                                                                

    ListView的Item能被选中的基础是它能获取Focus,也就是说我们可以通过将ListView中Item中包含的所有控件的focusable属性设置为false,这样的话ListView的Item自动获得了Focus的权限,也就可以被选中了,也就会响应onItemClickListener中的onItemClick()方法

解决办法就是将Button的Focus设置为非默认获取

方法一:将ListView的Item Layout的子控件focusable属性设置为false

方法二:对Item Layout的根控件android:descendantFocusability="blocksDescendant"

方法三:在实现ListView的Adapter的getView方法时,将button.setFocusable(false);

第三个问题:                                                                

       第三个问题是我认为最麻烦的,这里我一点点的分析。单击item中的选项时候,只有最后一个item响应。如下面所列:

     有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要写一个有按钮的xml文件,然后自然会想到用上面的方法定义一个适配器,然后将数据映射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显示出了按钮也无法添加按钮的响应,这时就要研究一下ListView是如何现实的了,而且必须要重写一个类继承BaseAdapter。下面的示例将显示一个按钮和一个图片,两行字如果单击按钮将删除此按钮的所在行。并告诉你ListView究竟是如何工作的。效果如下:

代码为:

public class setNetAdapter extends BaseAdapter {
	private Context context;
	private List<setNet> Messages;	//关联数据
	private boolean btn_Flag = false;
											
	public setNetAdapter(Context context, List<setNet> messages) {
		super();
		this.context = context;
		this.Messages = messages;
	}

	@Override
	public int getCount() {					
		return Messages.size();
	}

	@Override
	public Object getItem(int position) {	
		return Messages.get(position);	
	}

	@Override
	public long getItemId(int position) {	
		return position;
	}

	private ViewHolder holder;
	@Override								
	public View getView(int position, View convertView, ViewGroup parent) {
		holder = null;		
		setNet message = Messages.get(position);
		if (convertView == null) {
			holder =  new ViewHolder();
			convertView = LayoutInflater.from(context).inflate(R.layout.setting_net1, null);
			holder.id = (TextView) convertView.findViewById(R.id.set_net1_id);
			holder.catorgy = (TextView) convertView.findViewById(R.id.set_net1_txt);
			holder.name = (EditText) convertView.findViewById(R.id.set_net1_et1);
			holder.ip = (EditText) convertView.findViewById(R.id.set_net1_et2);
			holder.btn = (ImageView) convertView.findViewById(R.id.set_net1_imgBtn1);		
			convertView.setTag(holder);
		}else{
			holder = (ViewHolder)convertView.getTag();			
		}
		holder.id.setText(message.getId()+"");
		holder.catorgy.setText(message.getCatorgy().toString());
		holder.name.setText(message.getName().toString());
		holder.ip.setText(message.getIp().toString());
		holder.btn.setOnClickListener(new View.OnClickListener() {		
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				if(btn_Flag == true){				
					holder.name.setEnabled(false);
					holder.ip.setEnabled(false);
					if("".equalsIgnoreCase(holder.name.getText().toString()) ||
							holder.ip.length()<11){
						Toast.makeText(context, "输入有误,请重新输入", Toast.LENGTH_SHORT).show();
					}else{
						holder.btn.setImageDrawable(context.getResources().getDrawable(R.drawable.btn2));						
						//数据更新到数据库
						btn_Flag = false;
					}					
				}else{					
					holder.btn.setImageDrawable(context.getResources().getDrawable(R.drawable.btn3));
					btn_Flag = true;
				}
			}
		});
		return convertView;
	}
	static class ViewHolder {
		TextView id;
		TextView catorgy;
		EditText name;
		EditText ip;
		ImageView btn;	
	}
}

    系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写getView()方法。系统在绘制列表的每一行的时候将调用此方法。getView()有三个参数,position表示将显示的是第几行,covertView是从布局文件中inflate来的布局。我们用LayoutInflater的方法将定义好的vlist2.xml文件提取成View实例用来显示。然后将xml文件中的各个组件实例化(简单的findViewById()方法)。这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的listView就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点了,这是因为Button或ImageView抢夺了listView的焦点,只要布局文件中将Button或ImageView设置为没有焦点就OK了。

    问题出来了,为什么每次单击button的时候,只有最后一个item的ImageView去响应这个时间,也只有最后一个Item变化。有点小麻烦,只能仔细分析了。

if (convertView == null) {
	holder =  new ViewHolder();
	convertView = LayoutInflater.from(context).inflate(R.layout.setting_net1, null);
	holder.id = (TextView) convertView.findViewById(R.id.set_net1_id);
	holder.catorgy = (TextView) convertView.findViewById(R.id.set_net1_txt);
	holder.name = (EditText) convertView.findViewById(R.id.set_net1_et1);
	holder.ip = (EditText) convertView.findViewById(R.id.set_net1_et2);
	holder.btn = (ImageView) convertView.findViewById(R.id.set_net1_imgBtn1);		
	convertView.setTag(holder);
}else{
	holder = (ViewHolder)convertView.getTag();			
}


看这里,每次我们的holder都是更新的,完后我们采用了:

holder.btn.setOnClickListener(new View.OnClickListener() {		
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		if(btn_Flag == true){				
			holder.name.setEnabled(false);
			holder.ip.setEnabled(false);
			if("".equalsIgnoreCase(holder.name.getText().toString()) ||
					holder.ip.length()<11){
				Toast.makeText(context, "输入有误,请重新输入", Toast.LENGTH_SHORT).show();
			}else{
				holder.btn.setImageDrawable(context.getResources().getDrawable(R.drawable.btn2));						
				//数据更新到数据库
				btn_Flag = false;
			}					
		}else{					
			holder.btn.setImageDrawable(context.getResources().getDrawable(R.drawable.btn3));
			btn_Flag = true;
		}
	}
});

这里可以看出虽然每个ImageView都在监听,也会做出响应,但是holder停留在了最后一个Item对象中,响应的当然只是最后一个Item了。

这里我需要做出修改:public void onClick(View v)这里的View对应ImageView和你单击的还是对应的,需要设置flag。这里我做出的修改:

private List<ViewHolder> holders = new ArrayList<ViewHolder>();
private ViewHolder holder;
@Override								//获取要展示的项目View对象
public View getView(int position, View convertView, ViewGroup parent) {
	holder = null;		
	setNet message = Messages.get(position);
	if (convertView == null) {
		holder =  new ViewHolder();
		convertView = LayoutInflater.from(context).inflate(R.layout.setting_net1, null);
		holder.id = (TextView) convertView.findViewById(R.id.set_net1_id);
		holder.catorgy = (TextView) convertView.findViewById(R.id.set_net1_txt);
		holder.name = (EditText) convertView.findViewById(R.id.set_net1_et1);
		holder.ip = (EditText) convertView.findViewById(R.id.set_net1_et2);
		holder.btn = (ImageView) convertView.findViewById(R.id.set_net1_imgBtn1);		
		holder.btn.setTag(position+"");
		holders.add(holder);
		convertView.setTag(holder);
	}else{
		holder = (ViewHolder)convertView.getTag();			
	}
	holder.id.setText(message.getId()+"");
	holder.catorgy.setText(message.getCatorgy().toString());
	holder.name.setText(message.getName().toString());
	holder.ip.setText(message.getIp().toString());
	holder.btn.setOnClickListener(new View.OnClickListener() {		
		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			Log.i("adapter", v.getTag().toString());
			int index = Integer.parseInt(v.getTag().toString());
			holder = holders.get(index);
			if(btn_Flag == true){				
				holder.name.setEnabled(false);
				holder.ip.setEnabled(false);
				if("".equalsIgnoreCase(holder.name.getText().toString()) ||
						holder.ip.length()<11){
					Toast.makeText(context, "输入有误,请重新输入", Toast.LENGTH_SHORT).show();
				}else{
					holder.btn.setImageDrawable(context.getResources().getDrawable(R.drawable.btn2));						
					//数据更新到数据库
					btn_Flag = false;
				}					
			}else{					
				holder.btn.setImageDrawable(context.getResources().getDrawable(R.drawable.btn3));
				btn_Flag = true;
			}
		}
	});
	return convertView;
}

这里使用private List<ViewHolder> holders = new ArrayList<ViewHolder>();这样每次根据public void onClick(View v)中v.getTag来寻找单击的Item,选出对应的holders对应的holder,这里在做出响应即可。

 

 

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值