【问题标题】:Image flickering in imageView when list is scrolled or new image is downloaded in new row滚动列表或在新行中下载新图像时 imageView 中的图像闪烁
【发布时间】:2014-10-13 09:48:23
【问题描述】:

我遇到了许多类似于我的图像闪烁问题的问题。 我无法纠正它。作为一个初学者,我无法理解该怎么做。

这是我的代码.. 我在其中为图像设置缩略图。

private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
        final Uri uri) {
    new AsyncTask<String, Void, Bitmap>() {

        @Override
        protected Bitmap doInBackground(String... params) {

            Bitmap result = mBitmapCache.get(uri.toString());

            if (result == null)
                return getThumbnail(contentResolver, uri);
            else
                return result;
        }

        @Override
        protected void onPostExecute(Bitmap result) {



            if (uri != null && result != null) {
                //                    Log.d(TAG, "setThumbnail result not  null");
                //                    Log.d(TAG, "uri= "+uri);
                //                    Log.d(TAG, "aHolder.mMediaUri= "+aHolder.mMediaUri);
                mBitmapCache.put(uri.toString(), result);

                // confirm the holder is still paired to this uri
                if (!uri.equals(aHolder.mMediaUri)) {
                    return;
                }

                // set the thumbnail
                 ImageLoader imageLoader=ImageLoader.getInstance();
                imageLoader.init(ImageLoaderConfiguration.createDefault(getContext()));
                DisplayImageOptions options = new DisplayImageOptions.Builder()
           //     .showImageForEmptyUri(R.drawable.ic_empty)
           //   .showImageOnFail(R.drawable.ic_error)
                .resetViewBeforeLoading(true).cacheOnDisk(true)
                .imageScaleType(ImageScaleType.EXACTLY)
                .bitmapConfig(Bitmap.Config.RGB_565).considerExifParams(true)
                .cacheInMemory(true)
                .displayer(new FadeInBitmapDisplayer(300)).build();

                imageLoader.displayImage(uri.toString(), aHolder.mMediaThumbnail, options);
               // aHolder.mMediaThumbnail.setImageBitmap(result);
            } else {
                //                    Log.d(TAG, "setThumbnail result  null");
            }
          }
       }.execute();
   }

【问题讨论】:

  • 这是因为当您滚动列表时视图正在再次创建。构建一些缓存或使用 UniversalImageLoader 加载图像。
  • 你能详细说明一下..如何更改上面的代码

标签: android scroll imageview


【解决方案1】:

需要时在 ListView 中添加视图(参见https://stackoverflow.com/a/14108676/2274724)。因此,当您调用 notifyDataSetChange() 或滚动列表时,您的项目将创建。

因此,无论何时创建视图,您的图像都会从缓存中再次加载,从而导致闪烁。有一个解决办法:

首先在后台线程中加载图像(从网络或资产)然后像你一样创建一个位图缓存,而不是使用 AsyncTask 获取图像,如果它存在于位图缓存中直接获取图像(但这又不是一个好方法,因为它会停止闪烁,但当尺寸较大时,列表滚动将不流畅)。

我建议使用UniversalImageLoader。他们以更好的方式实现了内存缓存。

private void setThumbnail(final ContentResolver contentResolver, final ViewHolder aHolder,
        final Uri uri) {
ImageLoader.getInstance().displayImage(
                            uri.toString(),
                            aHolder.mMediaThumbnail, getDisplayOption());
}

// Add or remove option according to your requirement
private DisplayImageOptions getDisplayOption() {
        return new DisplayImageOptions.Builder()
                .showImageForEmptyUri(R.drawable.ic_launcher)
                .showImageOnLoading(R.drawable.ic_launcher)
                .showImageOnFail(R.drawable.ic_launcher).cacheInMemory(true)
                .cacheOnDisk(true).resetViewBeforeLoading(true)
                .displayer(new RoundedBitmapDisplayer(22))
                .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
                .bitmapConfig(Bitmap.Config.RGB_565).build();
    }

//Put it in your Application file and call it just once.
private void initImageLoader() {

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                getApplicationContext())
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .defaultDisplayImageOptions(getDisplayOption()).build();
        // Initialize ImageLoader with configuration.
        ImageLoader.getInstance().init(config);
    }

【讨论】:

  • 嘿,我试过 imageLoader。但是现在即使没有滚动或没有新的图像下载,图像也会闪烁。查看更新的代码。
  • 你不必把它放在 doInBackground 中,只需正常编写它,imageloader 将管理一切。查看更新的答案
  • 感谢 Chirag... 它帮助了:D
  • 嘿 Chirag.. 我需要一个帮助。我正在使用相机以纵向模式拍摄照片并使用 imgloader 设置它,它仅在纵向模式下设置图片,图像进入服务器。下次从服务器获取图像并且它在旋转时可见。我不明白出了什么问题。如果你能帮忙,请帮忙
  • stackoverflow.com/a/6124375/2274724。我想要正确的答案再问一个问题。
【解决方案2】:

在我使用之前:

  • 资产管理器
  • 输入流
  • 位图工厂
  • 所有这些都是为了得到一个位图
  • 最后使用imageView.setImageBitmap(bitmap)

现在我们有一些库可以帮助加载和缓存图像。

我使用Picasso 从网络加载图像。

但毕加索也可用于资产!

这是一个 Kotlin 示例:

val picassoPrefix = "file:///android_asset"

Picasso.get().load("$picassoPrefix/$assetsPath/$fileName")
    .placeholder(R.mipmap.ic_launcher_round)
    .into(imageView)

注意:

  • 我们也可以使用fetch方法进行预加载。
  • 就我而言,我认为没有必要,因为占位符是第一次显示,而下一次,图像会立即显示而不会闪烁。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多