`
aswang
  • 浏览: 838467 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Android ListView内部组件事件响应

 
阅读更多

 


最近项目需要实现一个下载模块,界面布局就采用常见的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;
		}
		
		@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又是不一样的,也就是每个按钮的事件监听器都是不一样的,这样分析之后又困惑了!

 

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

 

@Override
		public 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() {
					@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 ;
					}
				});
			}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以后,问题又出现了!

 

分享到:
评论
2 楼 aswang 2012-04-20  
wangbeyond6 写道
碰到 同样的 问题.


貌似通过ContentProvider来处理数据的变化可以解决,但是暂时没时间去测试这个!
1 楼 wangbeyond6 2012-04-20  
碰到 同样的 问题.

相关推荐

    Android代码-安卓常用组件

    安卓常用组件 ListViewLoad 说明:这是一个可以显示上拉加载更多的ListView. 实现方法: 创建要上拉后要显示的底部 编写自定义的view类继承ListView AndroidAnnotation 说明:安卓开发懒人框架(官网文档) ...

    Android基础课内实验报告.doc

    掌握Android常见UI控件的事件处理机制; 3. 掌握如何用Android常见的UI可视化数据; 4. 学会使用基本的UI控件编写程序。 实验内容: 内容1:参考教材P92的Spinner使用示例与P96的RatingBar使用示例完成这两个控件及...

    疯狂Android讲义源码

     1.6 Android应用的基本组件  介绍 31  1.6.1 Activity和View 31  1.6.2 Service 32  1.6.3 BroadcastReceiver 32  1.6.4 ContentProvider 32  1.6.5 Intent和IntentFilter 33  1.7 本章小结 33  第2章 ...

    Android开发艺术探索.任玉刚(带详细书签).pdf

    本书是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。本书从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层...

    Android基础知识详解

    4种响应菜单项单击事件的方式 56 显示和编辑文本的控件 57 TextView 57 CheckedTextView 60 EditText 60 ExtraEditText 61 AutoComplteteTextView、MultiAutoCompleteTextView (自动完成输入内容) 61 Button 63 ...

    精通ANDROID 3(中文版)1/2

    1.5.3 Android基础组件  1.5.4 高级UI概念  1.5.5 Android Service组件  1.5.6 Android媒体和电话组件  1.5.7 Android Java包  1.6 利用Android源代码  1.7 本书的示例项目  1.8 小结  第2章 设置...

    疯狂Android讲义.part2

    1.6 Android应用的基本组件 介绍 31 1.6.1 Activity和View 31 1.6.2 Service 32 1.6.3 BroadcastReceiver 32 1.6.4 ContentProvider 32 1.6.5 Intent和IntentFilter 33 1.7 本章小结 33 第2章 Android应用的界面编程...

    疯狂Android讲义.part1

    1.6 Android应用的基本组件 介绍 31 1.6.1 Activity和View 31 1.6.2 Service 32 1.6.3 BroadcastReceiver 32 1.6.4 ContentProvider 32 1.6.5 Intent和IntentFilter 33 1.7 本章小结 33 第2章 Android应用的界面编程...

    Android开发艺术探索

    《Android开发艺术探索》是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。《Android开发艺术探索》从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些...

    Android实例代码

    第3章、Android事件处理,包括按键响应机制和消息传递机制 3.2、基于监听器的事件处理: 3.3、基于回调的事件的处理: 3.4、响应系统设置的事件: 3.5、Handler消息传递机制: 第4章、深入理解Activity 4.1、...

    疯狂Android讲义(第2版)源代码 第6章~第9章

    第3章、Android事件处理,包括按键响应机制和消息传递机制 3.2、基于监听器的事件处理: 3.3、基于回调的事件的处理: 3.4、响应系统设置的事件: 3.5、Handler消息传递机制: 第4章、深入理解Activity 4.1、...

    Android典型技术模块开发详解

    第二篇 Android开发关键组件 第3章 Activity(活动) 3.1 什么是任务 3.2 Activity的生命周期 3.3 基本用法 3.3.1 创建Activity 3.3.2 启动Activity 3.3.3 窗口Activity 3.3.4 Activity生命周期验证 3.4 Activity...

    精通Android 3 (中文版)2/2

    1.5.3 Android基础组件  1.5.4 高级UI概念  1.5.5 Android Service组件  1.5.6 Android媒体和电话组件  1.5.7 Android Java包  1.6 利用Android源代码  1.7 本书的示例项目  1.8 小结  第2章 设置...

    CarsShow:演示任务

    任务:在ListView和Map上显示给定的JOSN响应( ) 使用的库: Google Maps Android API-要在我的应用程序中使用Google Maps。 Retrofit&OKHttp-与Web服务连接,因为处理Web服务响应非常简单明了。 Picasso-一...

    JAVA上百实例源码以及开源项目

    此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这...

    JAVA上百实例源码以及开源项目源代码

    此时此景,笔者只专注Android、Iphone等移动平台开发,看着这些源码心中有万分感慨,写此文章纪念那时那景! Java 源码包 Applet钢琴模拟程序java源码 2个目标文件,提供基本的音乐编辑功能。编辑音乐软件的朋友,这...

Global site tag (gtag.js) - Google Analytics