最近项目需要实现一个下载模块,界面布局就采用常见的ListView方式,实现的界面效果:


可是在事件监听的过程中出现问题了,内部组件如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;}@Overridepublic int getCount() {return data.size();}@Overridepublic Object getItem(int position) {if(position < data.size()){return data.get(position);}return null;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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() {@Overridepublic 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又是不一样的,也就是每个按钮的事件监听器都是不一样的,这样分析之后又困惑了!

最后改用下面的方式解决问题了,关键部分代码如下:

@Overridepublic View getView(int position, View convertView, ViewGroup parent){final Download down = (Download)getItem(position);Holder holder = null;if(convertView == null){convertView = inflater.inflate(resource, parent,false);holder = new Holder();holder.text = (TextView)convertView.findViewById(R.id.down_name);holder.bar = (ProgressBar)convertView.findViewById(R.id.down_progress);holder.imageBtn = (ImageButton)convertView.findViewById(R.id.down_pause);convertView.setTag(holder);//添加事件监听holder.imageBtn.setOnClickListener(new OnClickListener() {@Overridepublic 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 ;}});}else{holder = (Holder)convertView.getTag();}int progress = (int)(down.getDownloadSize()*100/down.getSize());String name = down.getName();holder.text.setText(name);holder.bar.setProgress(progress);Log.d(TAG, "状态:"+down.getStatus());return convertView;}

Holder定义如下:

class Holder {public TextView text;public ImageButton imageBtn;public ProgressBar bar;}

分析上面的代码,感觉没大的区别,虽然问题解决了,但是没搞懂为什么?

悲剧,在新插入item以后,问题又出现了!

更多相关文章

  1. Android自动化测试工具——Monkey .
  2. Android自动化测试工具——Monkey
  3. Android(安卓)Touch事件传递机制
  4. Android三种XML解析
  5. EditText单击触发onclick事件处理
  6. XML-layer-list
  7. Android标题栏沉浸效果
  8. android WebView组件使用总结
  9. Android(安卓)打开本地pdf文件,android 加载pdf文件

随机推荐

  1. 编译 go 源码为 android 动态库(so)
  2. Android(安卓)手机上安装并运行 Ubuntu 1
  3. Android(安卓)自定义控件外观
  4. Android(安卓)Spinner与适配器模式详解及
  5. Android温故之-BroadcastReceiver
  6. android实现横向滚动
  7. Android(安卓)的木马危机
  8. Android新手入门2016(2)--Mac下的Android开
  9. 【Android】在不同的线程池中执行AsyncTa
  10. 用c#开发安卓程序 (xamarin.android)系列