700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 解决自定义图库图片缩略图显示错乱的问题

解决自定义图库图片缩略图显示错乱的问题

时间:2024-06-21 13:43:17

相关推荐

解决自定义图库图片缩略图显示错乱的问题

解决自定义图库加载图片时,缩略图显示错乱的问题。

问题描述:

自定义图库里的图片缩略图显示重复,且有些位置显示空白。

出问题的代码如下:

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {String path = mImageInfos.get(position).getPath();Holder holder = null;if(convertView == null){holder = new Holder();convertView = mInflater.inflate(R.layout.picture_item, parent, false);holder.imageView = (ImageView) convertView.findViewById(R.id.iv_picture_item);holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb_picture_item);//convertView.setLayoutParams(new AbsListView.LayoutParams(mGridWidth, mGridHeight));convertView.setTag(holder);***holder.imageView.setTag(path);***}else{holder = (Holder) convertView.getTag();}setImageView(path, holder.imageView);holder.checkBox.setChecked(false);if (mIsSingleChoice) {if (position == mChoiceIndex) {holder.checkBox.setChecked(true);}} else {if (mChecked.contains(position)) {holder.checkBox.setChecked(true);}}return convertView;}

其中出问题代码在holder.imageView.setTag(path);因为在 convertView == null 时才会执行到该行代码,而当convertView 不为Null 时,执行不到此行代码,会复用上次设置的TAG,这样就会照成图片显示一样的问题。正确的做法是将holder.imageView.setTag(path);放到if else 之外执行,为每个View都设置一个不同的TAG标识,在使用的时候每个View取到的TAG都不一样,图片显示才不会重复。

正确的代码应该如下:

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {String path = mImageInfos.get(position).getPath();Holder holder = null;if(convertView == null){holder = new Holder();convertView = mInflater.inflate(R.layout.picture_item, parent, false);holder.imageView = (ImageView) convertView.findViewById(R.id.iv_picture_item);holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb_picture_item);//convertView.setLayoutParams(new AbsListView.LayoutParams(mGridWidth, mGridHeight));convertView.setTag(holder);}else{holder = (Holder) convertView.getTag();}//解决图片缩略图错乱的问题Log.d(TAG, "--setTag--path:"+path+"--position:"+position);holder.imageView.setTag(path);setImageView(path, holder.imageView);holder.checkBox.setChecked(false);if (mIsSingleChoice) {if (position == mChoiceIndex) {holder.checkBox.setChecked(true);}} else {if (mChecked.contains(position)) {holder.checkBox.setChecked(true);}}return convertView;}

附上相关代码供参考:

public class FragmentImagesGrid extends Fragment implements View.OnClickListener{public static final String TAG = "ImagesGrid";public static final boolean DEBUG = true;public static final String IMAGES_PATH = "images_path";public static final String IMAGES = "images";private ArrayList<ImageInfo> mImageInfos;private Context mContext; private ImagesAdapter mAdapter;private GridView mGridView;private ImageButton mIbtSend;private TextView mTvNumber;private LayoutInflater mInflater;//we save the checked info to the list// private SparseBooleanArray mChecked;private List<Integer> mChecked;private int mGridWidth;private int mGridHeight;private ArrayList<ImageInfo> mResultInfos;private boolean mIsSingleChoice = true;private int mChoiceIndex = -1;private ViewGroup mDialogView;private ImageView mIvDialogPre;private Button mBtDialogOk;private Button mBtDialogCancel;//private SoftReference<Bitmap> mDrawable = null;private Bitmap mBitmap;private Dialog mImageDialog;private final int MAX_SUM = 9; //单次最多可发送图片的数量@SuppressWarnings("unchecked")@Overridepublic void onCreate(Bundle savedInstanceState) {// super.onCreate(savedInstanceState);if(getArguments() != null){mImageInfos = (ArrayList<ImageInfo>) getArguments().get(FragmentImagesList.IMAGES_LIST);}else{mImageInfos = new ArrayList<ImageInfo>();}mResultInfos = new ArrayList<ImageInfo>();mContext = getActivity(); mInflater = LayoutInflater.from(mContext); //mChecked = new SparseBooleanArray();mChecked = new ArrayList<Integer>();mGridWidth = getActivity().getWindow().getDecorView().getWidth()/3;mGridHeight = mGridWidth;//createDialog();}private void createDialog() {mImageDialog = new Dialog(getActivity(), R.style.AletDialogFullScreen);mDialogView = (ViewGroup) mInflater.inflate(R.layout.image_dialog, null, false);mIvDialogPre = (ImageView) mDialogView.findViewById(R.id.iv_image_dialog);mBtDialogOk = (Button) mDialogView.findViewById(R.id.bt_select_ok);mBtDialogCancel = (Button) mDialogView.findViewById(R.id.bt_select_cancel);mImageDialog.setContentView(mDialogView);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {View layout = inflater.inflate(R.layout.images_grid_fragment, container, false);mGridView = (GridView) layout.findViewById(R.id.gv_images);mIbtSend = (ImageButton) layout.findViewById(R.id.ibt_pictrue_send);mIbtSend.setOnClickListener(this);mTvNumber = (TextView) layout.findViewById(R.id.tv_images_send_number);mAdapter = new ImagesAdapter(mGridView);mGridView.setAdapter(mAdapter);mGridView.setOnScrollListener(mAdapter);mGridView.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {if (DEBUG)Log.d(TAG, "item click xxxxxxxxxxx");previewImage(position);}});if(DEBUG)Log.d(TAG, "grid view width and height"+mGridView.getMeasuredHeight()+"//"+mGridView.getMeasuredWidth());return layout;}/**preview show a image* @param position the index what image have clicked.* */private void previewImage(int position) {if(mDialogView == null){createDialog();}final ImageInfo info = mImageInfos.get(position);final String path = info.getPath();File file = new File(path);if (file != null && file.isFile()) {Intent intent = new Intent(Intent.ACTION_VIEW);//intent.setType("image/*");intent.setDataAndType(Uri.fromFile(file), "image/*");//intent.setData(Uri.fromFile(file));//intent.setType("image/*");try {startActivity(intent);} catch(Exception e) {Log.d(TAG, "Failed to open image in photo. " + e.getMessage());}}//imageLoader.displayImage("file://" + path, mIvDialogPre, options, null, null);// final int index = position;// BitmapFactory.Options options = new BitmapFactory.Options();// options.inSampleSize = 8;// mBitmap = BitmapFactory.decodeFile(path, options);// //mDrawable = new SoftReference<Bitmap>(bitmap);// mIvDialogPre.setImageBitmap(mBitmap);////mImageDialog.show();//mBtDialogOk.setOnClickListener(new OnClickListener() {////@Override//public void onClick(View v) {// if(mIsSingleChoice){// mChoiceIndex = index;// }else{// mResultInfos.add(info);// mChecked.put(index, true);// mAdapter.updateCheckedCount(); // mAdapter.notifyDataSetChanged(); // }// mImageDialog.dismiss();// //dialog.getWindow().//}//});//mBtDialogCancel.setOnClickListener(new OnClickListener() {////@Override//public void onClick(View v) {// if(mIsSingleChoice){// mChoiceIndex = -1;// }else{// mResultInfos.remove(info);// mChecked.delete(index);// mAdapter.updateCheckedCount(); // } // mImageDialog.dismiss();//}//});//mImageDialog.setOnDismissListener(new OnDismissListener() {////@Override//public void onDismiss(DialogInterface dialog) {// //mDrawable = null;// recycler();//}//}); }protected void recycler() {// first we need set the source null that make mBitmap no uesed. then// recycle it.//Log.d(TAG, "recycle");//mIvDialogPre.setImageBitmap(null);//mBitmap.recycle();////mBitmap = null;//Log.d(TAG, "the image Source "+ mBitmap +" df"+mIvDialogPre.getDrawable()+" is recycle"+mBitmap.isRecycled());}/*** the adapter for gird view* */private class ImagesAdapter extends BaseAdapter implements OnScrollListener {/** * 记录所有正在下载或等待下载的任务。 */ private Set<BitmapWorkerTask> taskCollection; /** * 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。 */ private LruCache<String, Bitmap> mMemoryCache;/** * 第一张可见图片的下标 */ private int mFirstVisibleItem; /** * 一屏有多少张图片可见 */ private int mVisibleItemCount; /** * 记录是否刚打开程序,用于解决进入程序不滚动屏幕,不会下载图片的问题。 */ private boolean isFirstEnter = true; private GridView mImagesGrid;public ImagesAdapter(GridView gridView) {mImagesGrid = gridView;taskCollection = new HashSet<BitmapWorkerTask>(); // 获取应用程序最大可用内存 int maxMemory = (int) Runtime.getRuntime().maxMemory(); int cacheSize = maxMemory /6; // 设置图片缓存大小为程序最大可用内存的1/6 mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); } };}@Overridepublic int getCount() {//return mImageInfos.size();}@Overridepublic Object getItem(int position) {//return mImageInfos.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {String path = mImageInfos.get(position).getPath();Holder holder = null;if(convertView == null){holder = new Holder();convertView = mInflater.inflate(R.layout.picture_item, parent, false);holder.imageView = (ImageView) convertView.findViewById(R.id.iv_picture_item);holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb_picture_item);//convertView.setLayoutParams(new AbsListView.LayoutParams(mGridWidth, mGridHeight));convertView.setTag(holder);}else{holder = (Holder) convertView.getTag();}//解决图片缩略图错乱的问题Log.d(TAG, "--setTag--path:"+path+"--position:"+position);holder.imageView.setTag(path);setImageView(path, holder.imageView);holder.checkBox.setChecked(false);if (mIsSingleChoice) {if (position == mChoiceIndex) {holder.checkBox.setChecked(true);}} else {if (mChecked.contains(position)) {holder.checkBox.setChecked(true);}}final int index = position;final CheckBox box = holder.checkBox;holder.checkBox.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {if (checkPictureIsOutLimitSize(index)) {if(mIsSingleChoice){if(box.isChecked()){mChoiceIndex = index;}else{mChoiceIndex = -1;}notifyDataSetChanged(); }else{if(box.isChecked()){saveCheckedToArray(index);//mChecked.put(index, true);}else{//mChecked.delete(index);if(mChecked.contains(index)){mChecked.remove(mChecked.indexOf(index));}}updateCheckedCount();}}else {box.setChecked(false);notifyDataSetChanged();Toast.makeText(getActivity(), R.string.file_size_too_large,Toast.LENGTH_SHORT).show();}}});return convertView;}private class Holder{ImageView imageView;CheckBox checkBox;}/*** check whether current picture is more than 20M* @param position */private boolean checkPictureIsOutLimitSize(int position){String path = mImageInfos.get(position).getPath();File imageFile= new File(path); long imageFileSize=imageFile.getAbsoluteFile().length(); if (imageFileSize<20*1024*1024L) {return true;}else{return false;}}public void setImageView(String path,ImageView imageView){Bitmap bitmap = getBitmapFromMemoryCache(path);if(bitmap != null){imageView.setImageBitmap(bitmap);}else{imageView.setImageResource(R.drawable.message_picture);} }public Bitmap getBitmapFromMemoryCache(String key){return mMemoryCache.get(key); }public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemoryCache(key) == null) {mMemoryCache.put(key, bitmap); } } /** * 加载Bitmap对象。此方法会在LruCache中检查所有屏幕中可见的ImageView的Bitmap对象, * 如果发现任何一个ImageView的Bitmap对象不在缓存中,就会开启异步线程去下载图片。 * * @param firstVisibleItem * 第一个可见的ImageView的下标 * @param visibleItemCount * 屏幕中总共可见的元素数 */ private void loadBitmaps(int firstVisibleItem, int visibleItemCount) { //标准try {for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) { String path = mImageInfos.get(i).getPath(); Bitmap bitmap = getBitmapFromMemoryCache(path); if (bitmap == null) { BitmapWorkerTask task = new BitmapWorkerTask(); taskCollection.add(task); task.execute(path); }else{ImageView imageView = (ImageView) mImagesGrid.findViewWithTag(path); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } } } } catch (Exception e) { e.printStackTrace(); } } class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { /** * 图片的URL地址 */ private String path;@Override protected Bitmap doInBackground(String... params) { path = params[0]; // 在后台开始下载图片 Bitmap bitmap = createBitmapFromFile(path); if (bitmap != null) { // 图片下载完成后缓存到LrcCache中 addBitmapToMemoryCache(path, bitmap); } return bitmap; }@Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); // 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。 ImageView imageView = (ImageView) mGridView.findViewWithTag(path); if (imageView != null && bitmap != null) {imageView.setImageBitmap(bitmap); } taskCollection.remove(this); }/*** get bitmap from sdcardfile* */private Bitmap createBitmapFromFile(String path){Options opts = new Options();opts.inJustDecodeBounds = true; opts.inInputShareable = true;opts.inPurgeable = true;opts.inPreferredConfig = Bitmap.Config.RGB_565;BitmapFactory.decodeFile(path, opts);int imageHeight = opts.outHeight;int imageWidth = opts.outWidth;int sampleSize = getSampleSize(imageWidth,imageHeight);opts.inJustDecodeBounds = false;opts.inSampleSize = sampleSize;return BitmapFactory.decodeFile(path, opts);}private int getSampleSize(int width,int height){int inSampleSize = 1;if(width > mGridWidth || height > mGridHeight){int widthRatio = Math.round((float)width/mGridWidth);int heightRatio = Math.round(height/mGridHeight); inSampleSize =(widthRatio > heightRatio )? widthRatio : heightRatio;} return inSampleSize;} }/** * 取消所有正在下载或等待下载的任务。 */ public void cancelAllTasks() { if (taskCollection != null) { for (BitmapWorkerTask task : taskCollection) { task.cancel(false); } } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // 仅当GridView静止时才去下载图片,GridView滑动时取消所有正在下载的任务 if (scrollState == SCROLL_STATE_IDLE) { loadBitmaps(mFirstVisibleItem, mVisibleItemCount); } else { cancelAllTasks(); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Log.d("missyou", "on scroll view the firstVisibleItem "+firstVisibleItem+"visible Item"+visibleItemCount);mFirstVisibleItem = firstVisibleItem; mVisibleItemCount = visibleItemCount; // 下载的任务应该由onScrollStateChanged里调用,但首次进入程序时onScrollStateChanged并不会调用, // 因此在这里为首次进入程序开启下载任务。 if (isFirstEnter && visibleItemCount > 0) {loadBitmaps(mFirstVisibleItem, mVisibleItemCount); isFirstEnter = false; } } }protected void updateCheckedCount() {if(mChecked.size() == 0){mTvNumber.setText("");mIbtSend.setClickable(false);}else{mIbtSend.setClickable(true);mTvNumber.setText("("+String.valueOf(mChecked.size())+")");}}@SuppressWarnings("unchecked")public void changedData(Bundle peekData) {mImageInfos = (ArrayList<ImageInfo>) peekData.get(FragmentImagesList.IMAGES_LIST);if(mAdapter != null)mAdapter.notifyDataSetChanged();}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.ibt_pictrue_send:finishActivityOnresult();break;default:break;}}private void finishActivityOnresult() { if(mIsSingleChoice){if(mChoiceIndex == -1){return;} mResultInfos.add(mImageInfos.get(mChoiceIndex));}else{if(mChecked.size() == 0){return;} for(int i =0 ;i<mChecked.size();i++){int positon = mChecked.get(i);if(DEBUG)Log.d(TAG, "we check item position"+positon);mResultInfos.add(mImageInfos.get(positon));}} if(DEBUG){if(mIsSingleChoice){Log.d(TAG, "the result image path is"+mImageInfos.get(mChoiceIndex).getPath());}}Intent data = new Intent();//Bundle bundle = new Bundle();//bundle.putSerializable(IMAGES_PATH, mResultInfos);//data.putSerializable(IMAGES_PATH, mResultInfos);data.putExtra(IMAGES_PATH, mResultInfos);getActivity().setResult(Activity.RESULT_OK, data);getActivity().finish();} /*** set whether we just choice single image.* */public void setSingleChoice(boolean isSingle){this.mIsSingleChoice = isSingle;}/*** check whether current checked Picture's Number is more than MAX_SUM* @return true ,more than MAX_SUM; false otherwise*/private boolean checkPictureNumberIsMoreThanMaxSum(){if(mChecked.size() >= MAX_SUM){return true;}return false;}/*** save current index to Array in order* @param index ,current index to save*/private void saveCheckedToArray(int index){if(checkPictureNumberIsMoreThanMaxSum()){MDSVideoCallUtils.showMessage(R.string.image_exceed_max_sum);Log.e(TAG, "--saveCheckedToArray--removeindex:"+mChecked.get(0));mChecked.remove(0);if(mAdapter != null)mAdapter.notifyDataSetChanged();}Log.e(TAG, "--saveCheckedToArray--index:"+index);mChecked.add(index);updateCheckedCount();}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。