Android Adapter优化问题

      最近在使用BaseAdapter显示录制的视频文件时,又是遇到了各种奇葩问题。比如:

        1>文件个数多时,快速上下滑动时,速度明显缓慢,有点卡,更坑的是会出现异常退出;

        2>checkBox 点击选择时,其它页面的相同位置的checkBox也会被选中;

        3>自定义的checkBox的图标太小,如何增大checkBox的点击区域;

        4>进行加锁操作后,往缩列图中添加加锁文字,并不能得到及时的更新等情况。

    当然不得不说的是,出现这些问题的确是因为自己对adapter的理解不够深入,也一直没有注意这些问题,之前用的还是好好的,所以也就没有太在意,直到这次遇到问题了,不解决不行。

       下面先贴上项目中用到的adapter类,再慢慢分析:

public FilePageAdapter(List<HashMap<String, Object>> itemList,
			ListView videoFileListView,List<String> videoFilePath,View controlView,Context context) {
		super();

        mListView = videoFileListView;
        mVideoFilePath = videoFilePath;
        mControlView = controlView;
        mContext = context;
        mInflater = LayoutInflater.from(context);

        if (itemList != null) {
			this.itemList = itemList;
		} else {
			this.itemList = new ArrayList<HashMap<String, Object>>();
		}
		if (selectid != null && selectid.size() != 0) {
			selectid.clear();
		}

		mView = new HashMap<Integer, View>();
		isCheck = new HashMap<Integer, Boolean>();
		isMulChoice = true;

		for (int i = 0; i < itemList.size(); i++) {
			isCheck.put(i, false);
		}
		
	}
	

	public void updateView(String path,Bitmap bitmap){
		Log.d(TAG, "*** updateView();itemList.size is:"+itemList.size()
				+";bitmap is:"+bitmap
				+";path is:"+path);
		
		if (selectid != null && selectid.size() != 0) {
			selectid.clear();
		}
		
		for (int i = 0; i < itemList.size(); i++) {
			isCheck.put(i, false);
		}
		
		if(bitmap != null){
			ImageView mImageView = (ImageView) mListView.findViewWithTag(path);
			if (mListView != null && mImageView != null) {
				mImageView.setImageBitmap(bitmap);
			}
		}
		
		notifyDataSetChanged();
	}   

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return itemList.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		// return null;
		return mVideoFilePath.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}
        //全选操作
	public void checkAll() {
		for (int i = 0; i < itemList.size(); i++) {
			isCheck.put(i, true);
		}
		notifyDataSetChanged();
	}
	
	public List<String> selectIdGet(){
		return selectid;
	}
    public void selectIdAdd(String itemString){
    	selectid.add(itemString);
    }
    
    public void selectIdClear(){
    	selectid.clear();
    }
	@Override
	public View getView(final int position, View convertView,
			ViewGroup parent) {
		// TODO Auto-generated method stub
		Log.d(TAG, "*** getView()");
		
		final ViewHolder viewHolder;
		
		if (convertView == null) {
			viewHolder = new ViewHolder();
			
			convertView = mInflater.inflate(R.layout.files_list, null);
			viewHolder.file_lable = (MyImageView) convertView
					.findViewById(R.id.file_lable);

			viewHolder.file_check = (CheckBox) convertView
					.findViewById(R.id.file_check_box);
			viewHolder.fileName = (TextView) convertView
					.findViewById(R.id.file_name);
			viewHolder.fileSize = (TextView) convertView
					.findViewById(R.id.file_size);
			viewHolder.fileData = (TextView) convertView
					.findViewById(R.id.file_data);
			viewHolder.fileTime = (TextView) convertView
					.findViewById(R.id.file_time);
            
			viewHolder.file_lable
					.setOnMeasureListener(new OnMeasureListener() {
						public void onMeasureSize(int width, int height) {
							// TODO Auto-generated method stub
							mPoint.set(width, height);
						}
					});
           
		    convertView.setTag(viewHolder);				
		}else{
			viewHolder = (ViewHolder) convertView.getTag();
		}
		
		viewHolder.fileName.setText((String) itemList.get(position)
				.get(Global.mapFileName));
		viewHolder.fileSize.setText((String) itemList.get(position)
				.get(Global.mapFileSize));
		viewHolder.fileData.setText((String) itemList.get(position)
				.get(Global.mapFileData));
		viewHolder.fileTime.setText((String) itemList.get(position)
				.get(Global.mapFileTime));

		convertView.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// click the item and playVideo
				String path = new String();
				path = mVideoFilePath.get(position);

				Uri videoPath = Uri.parse(path);
				//播放视频
				VideoUtil.getInstance(mContext).playVideo(videoPath);
			}
		});
		
		String fileAbsolutePath = Global.defaule_storage_path + "/"
				+ itemList.get(position).get(Global.mapFileName);
		
		//the checkBox's Listener must before the init of checkBox
		viewHolder.file_check.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				CheckBox cb = (CheckBox) v;
				
				if(cb.isChecked()){
					mControlView.setVisibility(View.VISIBLE);
					selectid.add(mVideoFilePath.get(position));
					isCheck.put(position, true);
				}else{
					mControlView.setVisibility(View.GONE);
					selectid.remove(mVideoFilePath.get(position));
					isCheck.remove(position);
				}
			}
		});

		if (isCheck.get(position) != null) {
			Log.d(TAG, "*** isCheck.get(position) is:"+isCheck.get(position));
			
			viewHolder.file_check.setChecked(isCheck.get(position));
		}
		
		viewHolder.file_lable.setTag(fileAbsolutePath);
		
		ifFileLock = itemList.get(position).get(Global.mapFileLock)
				.toString();
		
		Log.d(TAG, "** before NativeVideoThumbnailLoader(); ifFileLock is: "+ifFileLock);
		//异步加载图片
		Bitmap bitmap = NativeVideoThumbnailLoader.getInstance()
				.loadNativeImage(fileAbsolutePath, mPoint, ifFileLock,
						new NativeImageCallBack() {
							@Override
							public void onImageLoader(Bitmap bitmap,
									String path) {
								Log.d(TAG, "***Callback onImageLoader();path is:"+path
										+";bitmap is:"+bitmap);
								
								ImageView mImageView = (ImageView) mListView
										.findViewWithTag(path);
								if (bitmap != null && mImageView != null) {
									mImageView.setImageBitmap(bitmap);
								}
							}
						});
		Log.e(TAG, "*** after NativeVideoThumbnailLoader: bitmap is:"+bitmap);
		
		if (bitmap != null) {
			viewHolder.file_lable.setImageBitmap(bitmap);
		} else {
			if (ifFileLock.equals(DataBaseUtil.dbFileLock)) {
				viewHolder.file_lable
						.setImageResource(R.drawable.file_video_lock);
			} else {
				viewHolder.file_lable
				        .setImageResource(R.drawable.file_video);
			}
		}
		return convertView;
	}
	
	static class ViewHolder {
		CheckBox file_check;
		TextView fileName;
		TextView fileSize;
		TextView fileData;
		TextView fileTime;

		MyImageView file_lable;
	}
}
         关于adapter原理相关的知识点,相信网上是有一大堆,而且都是分析的很不错。附上个人觉得不错关于adapter深入理解和优化的链接: 点击打开链接 http://mobile.51cto.com/abased-445617.htm。

         而我要说的点,是前面遇到的问题,也是为了给自己提个醒,下次写代码时,代码质量能得到提高:

         1>使用ViewHolder ,这样刷新view的时候 就不用每次都去解析 布局的xml文件;

         2>对checkBox的监听,需要放在对checkBox 的初始化之前;

         3>对checkBox只需要设置onClick 监听,不需要设置Change监听,在onClick监听中可以通过下面方式直接判断checkBox的选中状态

viewHolder.file_check.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				CheckBox cb = (CheckBox) v;
				
				if(cb.isChecked()){
					mControlView.setVisibility(View.VISIBLE);
					selectid.add(mVideoFilePath.get(position));
					isCheck.put(position, true);
				}else{
					mControlView.setVisibility(View.GONE);
					selectid.remove(mVideoFilePath.get(position));
					isCheck.remove(position);
				}
			}
		});
             4>关于增大checkBox的点击区域,如果只是有一个checkBox的话,可以增大checkBox的背景区域,对checkBox的背景进行监听,通过设置一个全局变量,通过判断全局变量的变化,判断checkBox的选中状态;

            如果是有多个checkBox的话,就需要设置 集合对相应的position的checkBox的状态进行记录,我做了如下的尝试: 定义的 public HashMap<Integer,Integer> checkBoxPos; 就是用来记录相应position的checkBox的选中状态,个人觉得思路是没有问题,不过测试的过程中,还是出现了checkBox的选中状态显示混乱的问题,不过通过log打印,实际的状态是没有错的,只是图标显示混乱,而我又找不大原因。所以最后干脆是直接在原来自定义checkBox的图片的基础上增大透明背景。

             

viewHolder.check_box__layout.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
//				CheckBox cb = (CheckBox) v;
				Log.d(TAG, "*** position is:"+position
						+";checkBoxPos.get(position) is:"+ checkBoxPos.get(position));
				
				if(0 == checkBoxPos.get(position)){
					checkBoxPos.put(position,1);
					mControlView.setVisibility(View.VISIBLE);
					selectid.add(mVideoFilePath.get(position));
					isCheck.put(position, true);
					viewHolder.file_check.setBackgroundResource(R.drawable.file_check_on);
				}else{
					checkBoxPos.put(position, 0);
					mControlView.setVisibility(View.GONE);
					selectid.remove(mVideoFilePath.get(position));
					isCheck.remove(position);
					viewHolder.file_check.setBackgroundResource(R.drawable.file_check_off);
				}
			}
		});
        本来是想写一些关于adapter的原理性的东西,奈何理解不够深入,也觉得别人写的的确很好了。在这里也只是想记录先自己遇到的问题以及解决的方法,相信只有想我这种菜鸟才会遇到这种问题吧。


posted @ 2015-08-01 22:59  小驰行动派  阅读(7)  评论(0编辑  收藏  举报  来源