3

For creating image slide show , I want to use image switcher with timer . I read this blog post it's very clear but it doesn't load images from network . Now i want load images from network with Glide Library .

This is MainActivity :

public class MainActivity extends Activity {
    private ImageSwitcher imageSwitcher;

    private int[] gallery = { http://www.helloworld.com/image1.png, http://www.helloworld.com/image2.png, http://www.helloworld.com/image3.png,
            http://www.helloworld.com/image4.png, };

    private int position;

    private static final Integer DURATION = 2500;

    private Timer timer = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher);
        imageSwitcher.setFactory(new ViewFactory() {

            public View makeView() {
                return new ImageView(MainActivity.this);
            }
        });

        // Set animations
        // https://danielme.com/2013/08/18/diseno-android-transiciones-entre-activities/
        Animation fadeIn = AnimationUtils.loadAnimation(this, R.anim.fade_in);
        Animation fadeOut = AnimationUtils.loadAnimation(this, R.anim.fade_out);
        imageSwitcher.setInAnimation(fadeIn);
        imageSwitcher.setOutAnimation(fadeOut);
    }

    // ////////////////////BUTTONS
    /**
     * starts or restarts the slider
     * 
     * @param button
     */
    public void start(View button) {
        if (timer != null) {
            timer.cancel();
        }
        position = 0;
        startSlider();
    }

    public void stop(View button) {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    public void startSlider() {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {

            public void run() {
                // avoid exception:
                // "Only the original thread that created a view hierarchy can touch its views"
                runOnUiThread(new Runnable() {
                    public void run() {
                        imageSwitcher.setImageResource(gallery[position]);
                        position++;
                        if (position == gallery.length) {
                            position = 0;
                        }
                    }
                });
            }

        }, 0, DURATION);
    }

    // Stops the slider when the Activity is going into the background
    @Override
    protected void onPause() {
        super.onPause();
        if (timer != null) {
            timer.cancel();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (timer != null) {
            startSlider();
        }

    }

}

I try to load images with glide but i don't know what should i do .

Sam Judd
  • 7,317
  • 1
  • 38
  • 38
Aron Glover
  • 385
  • 2
  • 15

3 Answers3

6

It's pretty easy to do, all you need is to load image using Glide to the ImageView that you can get from ImageSwitcher by method imageSwitcher.getCurrentView(). So you need to replace code inside run of your runOnUiThread method to the next code:

Glide.with(MainActivity.this)
    .load(gallery[position])
    .asBitmap()
    .listener(new RequestListener<String, Bitmap>() {
        @Override
        public boolean onException(Exception e, String model, Target<Bitmap> target, boolean isFirstResource) {
            return false;
        }

        @Override
        public boolean onResourceReady(Bitmap resource, String model, Target<Bitmap> target, boolean isFromMemoryCache, boolean isFirstResource) {
            position++;
            if (position == gallery.length) {
                position = 0;
            }
            imageSwitcher.setImageDrawable(new BitmapDrawable(getResources(), resource));
            return true;
        }
    }).into((ImageView) imageSwitcher.getCurrentView());

Also don't forget to replace your image urls with appropriate urls (you now have there some dummy urls I see). So your gallery array should be a String[] array.

Don't forget also to include android.permission.INTERNET to your AndroidManifest.xml.

And finally you need to change android:layout_width property of your ImageSwitcher to match_parent in xml as Glide won't load image in it otherwise.

romtsn
  • 11,704
  • 2
  • 31
  • 49
1

I think the approved answer is great but it is missing something key. When they update the current image, this is basically just replacing the one in view. This means we might as well not use the ImageSwitcher at all. What we need to do, is update the next view and then show it. This will allow us to also see any transition effects we have added.

I have separated all this logic out within my own code to make it clean, but here it is in RAW form.

Setting up of your ImageSwitcher

   

    Animation in = AnimationUtils.loadAnimation(this,android.R.anim.fade_in);
       Animation out = AnimationUtils.loadAnimation(this,android.R.anim.fade_out);
       imageSwitcher.setFactory(() -> {
                ImageView imageView = new ImageView(getApplicationContext());
                imageView.setLayoutParams(new FrameLayout.LayoutParams(
                        FrameLayout.LayoutParams.MATCH_PARENT,
                        FrameLayout.LayoutParams.MATCH_PARENT
                ));
                return imageView;
            });
       imageSwitcher.setInAnimation(in);
       imageSwitcher.setOutAnimation(out);

  

Call this to then update the next image

   

    RequestOptions requestOptions = new 
       RequestOptions().diskCacheStrategy(DiskCacheStrategy.ALL);
       Bitmap nextImage = getAppropriateImage();
       GlideApp.with(this)
          .load(nextImage)
          .apply(requestOptions)
          .into((ImageView) imageSwitcher.getNextView());
       imageSwitcher.showNext();

Aidan Lee
  • 73
  • 5
  • 2 comments to improve this answer: 1) don't call showNext() until the 'next' image is loaded 2) set the 'next' view to INVISIBLE like a reply below suggests – jpage4500 Dec 01 '21 at 16:04
  • @jpage4500 Could you please share your solution? – Tara Dec 14 '22 at 10:46
0

I used the version of @rom4ek but I had some crash:

Fatal Exception: java.lang.RuntimeException Canvas: trying to use a recycled bitmap android.graphics.Bitmap@7ad49c4

I think that this is because the drawable is not set into the same ImageView passed to into(...).

I changed it to use the "next view". We have to set the visibility from GONE to INVISIBLE for Glide.

imageSwitcher.getNextView().setVisibility(View.INVISIBLE);
Glide.with(...)
    .load(url)
    .listener(new RequestListener<String, Bitmap>() {
        @Override
        public boolean onException(Exception e, String model, Target<Drawable> target, boolean isFirstResource) {
            return false;
        }

        @Override
        public boolean onResourceReady(Drawable resource, String model, Target<Drawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            imageSwitcher.setImageDrawable(resource);
            return true;
        }
    }).into((ImageView) imageSwitcher.getNextView());

Kotlin version:

it.nextView.visibility = View.INVISIBLE
Glide.with(...)
    .load(url)
    .listener(object : RequestListener<Drawable> {
        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Drawable>?,
            isFirstResource: Boolean
        ): Boolean {
            return false
        }

        override fun onResourceReady(
            resource: Drawable?,
            model: Any?,
            target: Target<Drawable>?,
            dataSource: DataSource?,
            isFirstResource: Boolean
        ): Boolean {
            it.setImageDrawable(resource)
            return true
        }
    })
    .into(it.nextView as ImageView)
Kevin Robatel
  • 8,025
  • 3
  • 44
  • 57
  • >> I changed it to use the "next view". We have to set the visibility from GONE to INVISIBLE for Glide. This worked for me as I was originally having issues with Glide loading the image into the 'next' view.. I suspect it's because that view wasn't visible and Glide just skipped it – jpage4500 Dec 01 '21 at 16:02