3

I have gone through many questions similar to mine of images flickering problem. I am not able to correct it. Being a beginner,I am not able to understand what to do.

Here is my code.. where I set thumbnail for a image.

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();
   }
Harish Vats
  • 662
  • 6
  • 21

2 Answers2

2

In ListView view is added when it is required (See https://stackoverflow.com/a/14108676/2274724). So your item will create when you call notifyDataSetChange() or scroll your list.

So whenever your view is created your image will load again from cache which results into flickering. There is a solution :

First Load image in background thread (Either from network or assets) then create a bitmap cache as u did but instead of getting image using AsyncTask get Image directly if it exist in bitmap cache (But this is again not a good way because it will stop flickering but list scroll will not be smooth when size is large).

I will Suggest use UniversalImageLoader. They implemented memory cache in much better way.

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);
    }
Community
  • 1
  • 1
Chirag Jain
  • 1,612
  • 13
  • 20
  • Hey, I tried imageLoader. But now images are flickering even when the when there is no scrolling or no new downloading of images. See the updated code. – Harish Vats Oct 14 '14 at 04:46
  • You don't have to put it in doInBackground just write it normally imageloader will manage everything. See updated answer – Chirag Jain Oct 14 '14 at 05:46
  • Hey Chirag.. I need one help. I am taking pic using camera in portrait mode and setting it using imgloader and It is setting pic in portrait mode only and the image goes to server. Next time image is fetched from server and It is visible as rotated. I am not getting whats going wrong. plz if u can help – Harish Vats Oct 17 '14 at 08:24
  • See http://stackoverflow.com/a/6124375/2274724. I want proper anwer ask another question. – Chirag Jain Oct 17 '14 at 09:28
0

Before I was using:

  • AssetManager
  • InputStream
  • BitmapFactory
  • All of this to get a Bitmap
  • And finally use imageView.setImageBitmap(bitmap)

Nowadays we have libraries that help loading and caching images.

I have used Picasso for loading images from the web.

But Picasso is available for assets too!

Here is a Kotlin example:

val picassoPrefix = "file:///android_asset"

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

Note:

  • We can use the fetch method for preloading too.
  • In my case I don't think it's necessary, since the placeholder is displayed for the first time, and for the next times, the images are displayed immediately without flickering.
JCarlosR
  • 1,598
  • 3
  • 19
  • 32