精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-04-19
最后修改:2012-04-19
可是在事件监听的过程中出现问题了,内部组件如Button无法捕获到点击事件OnClick : 这个问题还好解决,通过给Button设定
android:focusable="false" 然后给ListView的item布局文件的最顶层组件添加:
android:descendantFocusability="blocksDescendants" 这样就可以同时相应Button的点击事件和Item的点击事件了。
但是,在点击后面的下载按钮时,会出现同时有两个按钮状态发生变化,ListView的Adapter的代码如下:
private class DownloadListAdapter extends BaseAdapter{ private Context mContext; private LayoutInflater inflater; private List<Download> data; private int resource; public DownloadListAdapter(Context context, List<Download> data, int resource) { super(); mContext = context; inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.data = data; this.resource = resource; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { if(position < data.size()){ return data.get(position); } return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent){ final Download down = (Download)getItem(position); if(convertView == null){ convertView = inflater.inflate(resource, parent,false); ImageButton btn = (ImageButton)convertView.findViewById(R.id.down_pause); //添加事件监听 btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.d(TAG,"添加事件监听:"+ v.hashCode() +" - "+down.getId()); if(down.getStatus() == Downloader.STATUS_RUNNING){ Log.d(TAG, "暂停下载 : "+down.getId()); mDownloader.pause(down.getId()); down.setStatus(Downloader.STATUS_PAUSED); }else if(down.getStatus() == Downloader.STATUS_PAUSED){ Log.d(TAG, "继续下载 : "+down.getId()); mDownloader.continueDownload(down.getId()); down.setStatus(Downloader.STATUS_RUNNING); } //DownloadListAdapter.this.notifyDataSetChanged(); return ; } }); } TextView nameText = (TextView)convertView.findViewById(R.id.down_name); ProgressBar bar = (ProgressBar)convertView.findViewById(R.id.down_progress); ImageButton btn = (ImageButton)convertView.findViewById(R.id.down_pause); int progress = (int)(down.getDownloadSize()*100/down.getSize()); String name = down.getName(); nameText.setText(name); bar.setProgress(progress); Log.d(TAG, "状态:"+down.getStatus()); return convertView; } 事件监听器是在每个Item第一次初始化的时候添加的,而且也只添加了一次,同时日志跟踪,在点击最后一个按钮的时候,OnClick里面的日志也显示只调用了一次,但是界面的上的第一个按钮的状态也跟着发生变化。
纠结了很久都没弄清楚到底是哪里的问题。分析可能的原因:ImageButton btn =(ImageButton)convertView.findViewById(R.id.down_pause);是通过这种方式获得,而ListView里面所有的Item都共用一个布局文件,也就是上面的所有的convertView都是通过一个布局文件构造出来的,感觉这里会发生问题,但是貌似又没问题,在添加事件监听的过程中,打印的对应组件的hashCode又是不一样的,也就是每个按钮的事件监听器都是不一样的,这样分析之后又困惑了!
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-04-20
最后修改:2012-04-20
建议你不要再listitem上使用 button 或者 imageButton , 使用imageview 没有问题的
button 和 imageButton 他们和listitem 的焦点事件有冲突(我是这么理解的) 我觉得如果使用imageview 不会出现问题的 |
|
返回顶楼 | |
发表时间:2012-04-20
whao189 写道 建议你不要再listitem上使用 button 或者 imageButton , 使用imageview 没有问题的
button 和 imageButton 他们和listitem 的焦点事件有冲突(我是这么理解的) 我觉得如果使用imageview 不会出现问题的 这个建议不错,我看过安智市场的下载界面,感觉里面像是用的ImageView,而不是Button,所以后面打算修改为ImageView来查看效果! 非常感谢你的建议! |
|
返回顶楼 | |
发表时间:2012-04-20
最后修改:2012-04-20
看来你不懂listview的运行原理啊 listview里面的item都是不回收的,所以你获得convertView对象可能就是你上次用的,是有状态的。
这个错误初学者很容易范,我以前也犯过这个错误,解决方法就是把item的所有状态都放在item的bean里,在getview里面从新设置convertView的状态(比如某个button是点击了还是没点击,某个图片背景等等) 而且在处理button里面的事件的时候也要做特殊处理,我的做法是 button.setTag(posation); 不然你的点击事件也会出现絮乱 |
|
返回顶楼 | |
发表时间:2012-04-20
Cindy_Lee 写道 看来你不懂listview的运行原理啊 listview里面的item都是不回收的,所以你获得convertView对象可能就是你上次用的,是有状态的。
这个错误初学者很容易范,我以前也犯过这个错误,解决方法就是把item的所有状态都放在item的bean里,在getview里面从新设置convertView的状态(比如某个button是点击了还是没点击,某个图片背景等等) 而且在处理button里面的事件的时候也要做特殊处理,我的做法是 button.setTag(posation); 不然你的点击事件也会出现絮乱 多谢分析!对ListView的渲染机制我一直没认真琢磨过,很多时候都是会用就行,看来这样是不行的。 button.setTag(posation)这个做法不错,没有尝试过,之间一直不知道如何获取点击按钮对应的位置,可以用这个方法了! |
|
返回顶楼 | |
发表时间:2012-04-21
HI,你的适配器是继承BaseAdapter的吧,那样的话ListView的每行的控件就都能监听,比如你的Button。这个网上很多。
你点击Button的时候,取button的getPareten()就可以的到Button的外面一层的控件paretenView,然后通过paretenView.findViewByid的方法就可以找到你要的控件了。 |
|
返回顶楼 | |
发表时间:2012-04-21
endual 写道 HI,你的适配器是继承BaseAdapter的吧,那样的话ListView的每行的控件就都能监听,比如你的Button。这个网上很多。 你点击Button的时候,取button的getPareten()就可以的到Button的外面一层的控件paretenView,然后通过paretenView.findViewByid的方法就可以找到你要的控件了。 现在 就是点击列表中的button出问题了,不过可以通过Cindy_Lee说的办法来改正这个问题,最近没时间完善,后面测试OK了再来改贴子。 这个方法getPareten 估计你拼错了,应该是getParent() |
|
返回顶楼 | |
发表时间:2012-04-22
我一般是把item的内的button组件去掉,将事件放到item本身上去,这样我觉得还好些。仅仅是个人观点。
|
|
返回顶楼 | |
发表时间:2012-04-23
夜之son 写道 我一般是把item的内的button组件去掉,将事件放到item本身上去,这样我觉得还好些。仅仅是个人观点。 但是,我需要在item后面放置一个按钮用来控制item的状态 |
|
返回顶楼 | |
发表时间:2012-04-23
aswang 写道 夜之son 写道 我一般是把item的内的button组件去掉,将事件放到item本身上去,这样我觉得还好些。仅仅是个人观点。
但是,我需要在item后面放置一个按钮用来控制item的状态 item本身就是一个view,你拿到了view,剩下的你想怎么变不就怎么变吗? |
|
返回顶楼 | |