Intereting Posts
Не удалось отладить с помощью gdb под Android и NDK, запуская приложение Gdb crashes Android Service.startForeground НЕ уважает уникальность идентификатора уведомления Corova build –release android всегда выбирает самый высокий уровень api Как сделать расстояние между буквами в Android TextView? Приемник смены режима звонка Широковещательный приемник? Почему backspace перестает работать, если я устанавливаю TYPE_TEXT_FLAG_NO_SUGGESTIONS в моем AutocompleteTextView? Воспроизведение видео в формате HTML5 на полноэкранном режиме в веб-обозревателе Android Не удалось подключиться к службе камеры Как инструмент HierarchyViewer от android studio знает свойства просмотров экрана Android Android StaggeredGridView внутри высоты ListView Неудачное окно поиска – разные варианты поведения из одного приложения на 2 галактических связях Сделайте анимацию Android более плавной, когда во время анимации отображается клавиатура Java.net.SocketException: sendto failed: EPIPE (Сломанная труба) через соединение с данными на localhost Градиент развертки: что это такое и его примеры Выбранный обратный вызов Spinner активируется дважды после вращения, если выбрана ненулевая позиция

Ленивое загрузочное изображение с индикатором выполнения делает повреждение изображения при отображении изображения

У меня есть приложение, отображающее изображения с сервера. Теперь я лениво загружаю свои изображения. Поэтому изначально я показываю индикатор выполнения при загрузке изображения. Я View.INVISIBLE индикатор выполнения, устанавливая его атрибут visibility в View.INVISIBLE и изображение появляется. Это файл макета, который я использую для изображений

 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" > <ImageView android:id="@+id/imageView1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center" android:contentDescription="@string/app_name" android:scaleType="centerInside" android:src="@drawable/ic_launcher" /> <RelativeLayout android:id="@+id/loading_layout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/white" > <ProgressBar android:id="@+id/progressBar1" style="?android:attr/progressBarStyleSmall" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:background="@android:color/white" /> </RelativeLayout> </FrameLayout> 

Проблема Когда индикатор выполнения исчезнет, ​​изображение отображается на экране, но повреждено. Как это изображение

Когда я обновляю список изображений, загруженных из каталога кеша, и когда они отображаются на экране, они отображаются корректно без какого-либо повреждения.

Введите описание изображения здесь

Класс ImageLoader i используется для ленивого изображения загрузки

 public class ImageLoader { // @@ JUST FOR THIS PROJECT BaseAdapter mAdapter; // @@ MemoryCache memoryCache = new MemoryCache(); FileCache fileCache; private Map<ImageView, String> imageViews = Collections .synchronizedMap(new WeakHashMap<ImageView, String>()); ExecutorService executorService; boolean addRoundCournerAndStroke = false; boolean scale = false; boolean localfile = false; int default_image; public ImageLoader(Context context, boolean flag, boolean scale, boolean localfile) { fileCache = new FileCache(context); this.addRoundCournerAndStroke = flag; executorService = Executors.newFixedThreadPool(5); this.scale = scale; this.localfile = localfile; } public ImageLoader(Context context, boolean flag, boolean scale, boolean localfile, int default_image_id) { this(context, flag, scale, localfile); this.default_image = default_image_id; } public ImageLoader(Context context, boolean flag, boolean scale, boolean localfile, int default_image_id, BaseAdapter adapter) { this(context, flag, scale, localfile); this.default_image = default_image_id; this.mAdapter = adapter; } public void DisplayImage(String url, ImageView imageView) { imageViews.put(imageView, url); Bitmap bitmap = memoryCache.get(url); if (bitmap != null) { changeProgressBarVisibilty(imageView, false); imageView.setImageBitmap(bitmap); } else { queuePhoto(url, imageView); imageView.setImageResource(this.default_image); } } private void queuePhoto(String url, ImageView imageView) { PhotoToLoad p = new PhotoToLoad(url, imageView); executorService.submit(new PhotosLoader(p)); } private Bitmap getBitmap(String url) { File f = null; if (localfile) f = new File(url); else f = fileCache.getFile(url); // Log.d("bytes", "decode"); // from SD cache Bitmap b = decodeFile(f); if (b != null) return b; // from web try { Bitmap bitmap = null; URL imageUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) imageUrl .openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(30000); conn.setInstanceFollowRedirects(true); InputStream is = conn.getInputStream(); OutputStream os = new FileOutputStream(f); Utils.CopyStream(is, os); os.close(); bitmap = decodeFile(f); // //Log.d("bytes", "decode"); return bitmap; } catch (Exception ex) { ex.printStackTrace(); return null; } } private Bitmap decodeFileWithoutScaling(File f) { try { BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = 1; //o2.inPurgeable = true; if (this.localfile) return BitmapFactory.decodeFile(f.getAbsolutePath(), o2); else return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) { } return null; } private Bitmap decodeFile(File f) { if (this.scale) { return decodeFileWithScalling(f); } else { return decodeFileWithoutScaling(f); } } // decodes image and scales it to reduce memory consumption private Bitmap decodeFileWithScalling(File f) { try { // decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; // o.inPurgeable = true; if (this.localfile) BitmapFactory.decodeFile(f.getAbsolutePath(), o); else BitmapFactory.decodeStream(new FileInputStream(f), null, o); // Find the correct scale value. It should be the power of 2. final int REQUIRED_SIZE = 70; int width_tmp = o.outWidth, height_tmp = o.outHeight; // Log.d("width", width_tmp + ""); // Log.d("height", height_tmp + ""); int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } // decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; // o2.inPurgeable = true; // Log.d("after shave width", o2.outWidth + ""); // Log.d("after shave height", o2.outHeight + ""); if (this.localfile) return BitmapFactory.decodeFile(f.getAbsolutePath(), o2); else return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); } catch (FileNotFoundException e) { } return null; } // Task for the queue private class PhotoToLoad { public String url; public ImageView imageView; public PhotoToLoad(String u, ImageView i) { url = u; imageView = i; } } class PhotosLoader implements Runnable { PhotoToLoad photoToLoad; PhotosLoader(PhotoToLoad photoToLoad) { this.photoToLoad = photoToLoad; } public void run() { if (imageViewReused(photoToLoad)) { return; } Bitmap bmp = getBitmap(photoToLoad.url); // if (addRoundCournerAndStroke) { // // bmp = ImageHelper.rotateAndFrame(bmp, 10); // bmp = ImageHelper.getRoundedCornerBitmap(bmp, 10); // } memoryCache.put(photoToLoad.url, bmp); if (imageViewReused(photoToLoad)) return; BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad); Activity a = (Activity) photoToLoad.imageView.getContext(); a.runOnUiThread(bd); } } boolean imageViewReused(PhotoToLoad photoToLoad) { String tag = imageViews.get(photoToLoad.imageView); if (tag == null || !tag.equals(photoToLoad.url)) return true; return false; } // Used to display bitmap in the UI thread class BitmapDisplayer implements Runnable { Bitmap bitmap; PhotoToLoad photoToLoad; public BitmapDisplayer(Bitmap b, PhotoToLoad p) { bitmap = b; photoToLoad = p; } public void run() { if (imageViewReused(photoToLoad)) return; changeProgressBarVisibilty(photoToLoad.imageView, false); if (bitmap != null) { photoToLoad.imageView.setImageBitmap(bitmap); } else { photoToLoad.imageView .setImageResource(ImageLoader.this.default_image); } if (mAdapter != null) { mAdapter.notifyDataSetChanged(); } } } private void changeProgressBarVisibilty(ImageView image, boolean visible) { ViewGroup layout = (ViewGroup) image.getParent(); try { View v = layout.findViewById(R.id.loading_layout); v.setVisibility(visible ? View.VISIBLE : View.GONE); } catch (Exception ex) { ex.printStackTrace(); } } public void clearCache() { memoryCache.clear(); fileCache.clear(); } } 

Solutions Collecting From Web of "Ленивое загрузочное изображение с индикатором выполнения делает повреждение изображения при отображении изображения"

Попробуйте использовать ProgressDialog вместо Progressbar. ProgressDialog также может использовать индикатор выполнения. ProgressDialog не является типом XML. Поэтому вы можете показать () или отклонить () метод. Возможно, это не проблема. Я думаю, что эта проблема исходит от RelativeLayout. Если вы используете ProgressBar Visiblity, RelativeLayout все еще остается видимым (но не имеет фона). Также RelativeLayout имеет любой элемент. Я предполагаю, что Пустой макет дал вам коррупцию. Лучше всего использовать ProgressDialog.

Поврежденное изображение показывает поврежденные артефакты JPEG.

Ваша проблема может возникнуть из метода BitmapFactory.decodeStream . Не все JPEG-файлы оптимизированы для декодирования на лету («прогрессивные»), поэтому они, возможно, должны быть доступны в целом до правильного декодирования. Обычно прогрессивные изображения могут быть декодированы сверху вниз, но это, возможно, не выполняется для всех файлов, или декодер может иметь некоторые недостатки, которые мешают этому.

С другой стороны, если изображение затем извлекается из кэшированного файла, используется BitmapFactory.decodeFile который не нуждается в заботе о потоковых данных и может случайно получить доступ к файлу изображения для декодирования JPEG. Если вам не нужны потоковые обновления дисплея при загрузке изображения, я бы предложил установить этот путь кода и всегда загружать все изображение перед декодированием.

Я думаю, вы можете попытаться установить видимость как View.GONE , потому что когда вы устанавливаете View.INVISIBLE View по-прежнему занимает место, и, как сказал Tae, это могут быть некоторые проблемы с RelativeLayout.

ура