nuhkoca
nuhkoca

Reputation: 1943

Set Background Image to Relative Layout using Glide in Android

How can I do this using Glide? I want to cache image to use it another time also. Thanks in advance.

Upvotes: 45

Views: 46180

Answers (8)

Chad Schultz
Chad Schultz

Reputation: 7860

I needed to set the background of an ImageView (so I could set the foreground to a different image). I eventually found https://github.com/bumptech/glide/issues/938#issuecomment-176150770, but that's a bit out of date. Through experimentation I altered it to the following to work with Glide 4 (similar to some of the other answers here):

/** @see ImageViewTarget
 */
abstract class ViewBackgroundTarget<Z>(view: View) : CustomViewTarget<View?, Z>(view) {
    override fun onLoadFailed(errorDrawable: Drawable?) {
    }

    override fun onResourceCleared(placeholder: Drawable?) {
        // This line is ESSENTIAL or else there will be occasional crashes like:
        // "java.lang.NullPointerException: Attempt to invoke virtual method 
        // 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference"
        view!!.background = placeholder
    }
}

/** @see BitmapImageViewTarget
 */
class BitmapViewBackgroundTarget(view: View) : ViewBackgroundTarget<Bitmap>(view) {
    override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
        view!!.background = BitmapDrawable(view.resources, resource)
    }
}

/** @see DrawableImageViewTarget
 */
class DrawableViewBackgroundTarget(view: View) : ViewBackgroundTarget<Drawable>(view) {
    override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
        view!!.background = resource
        if (resource is GifDrawable) {
            resource.setLoopCount(LOOP_FOREVER)
            resource.start()
        }
    }
}

use this with

Glide.with(myImageView)
        .load(imageUrl)
        .into(DrawableViewBackgroundTarget(myImageView))

I assume this would work easily for a RelativeLayout or other View types as well.

Upvotes: 0

Kasun Thilina
Kasun Thilina

Reputation: 1681

Here's the code for Kotlin

  • Glide 4.9.x
  • Since the SimpleTarget is deprecated now we have to use CustomTarget as below
Glide.with(this).load(UCrop.getOutput(data)).into(object : 
                        CustomTarget<Drawable>() {
                        override fun onLoadCleared(placeholder: Drawable?) {
                            TODO("Not yet implemented")
                        }

                        override fun onResourceReady(
                            resource: Drawable,
                            transition: Transition<in Drawable>?
                        ) {
                            ib_pet_profile_image.background=resource
                        }

                    })

Upvotes: 6

Cyrus
Cyrus

Reputation: 9425

Glide.with(ctx).asBitmap().load(url).centerCrop().into(object: CustomTarget<Bitmap>(){
            override fun onLoadCleared(placeholder: Drawable?) {
            }

            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                val wRatio = view.width/resource.width.toFloat()
                val hRatio = view.height / resource.height.toFloat()

                val minRatio = min(wRatio,hRatio)

                val destBitmap = Bitmap.createScaledBitmap( resource,(resource.width*minRatio).toInt(), (resource.height*minRatio).toInt(),false)
               view.background = BitmapDrawable(resources,destBitmap)
            }
        })

This works for me

PS: There would be an error when the bitmap is too large

java.lang.RuntimeException: Canvas: trying to draw too large bitmap.

So you'd better scale that bitmap like what i did in above code

Upvotes: 1

Chintan Desai
Chintan Desai

Reputation: 2707

You can load an image in a RelativeLayout like this. I'm just showing you the hard part which is setting an image to the background.

For Glide version before 4.X

Glide.with(this).load(imageViewPath).asBitmap().into(new SimpleTarget<Bitmap>(relLayoutWidth, relLayoutHeight) {
    @Override
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
        Drawable drawable = new BitmapDrawable(context.getResources(), resource);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            yourRelativeLayout.setBackground(drawable);
        }
    }
});

For caching, refer to this page: Caching and Cache Invalidation.

Update for Glide v4 onward:

GlideApp.with(this).load(R.drawable.backgroundimage).into(new SimpleTarget<Drawable>() {
            @Override
            public void onResourceReady(Drawable resource, Transition<? super Drawable> transition) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    yourRelativeLayout.setBackground(resource);
                }
            }
        });

Upvotes: 66

DeePanShu
DeePanShu

Reputation: 1326

(SimpleTarget class is Deprecated So using CustomTarget class to Load image)

You can load an image in a RelativeLayout like this. I'm just showing you the hard part which is setting an image to the background.

For Glide version before 4.X (Without Deprecation)

Glide.with(this).load(ServiceGenerator.BASE_URL + url).into(new CustomTarget<Drawable>() {
            @Override
            public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                yourRelativeLayout.setBackground(resource);
            }

            @Override
            public void onLoadCleared(@Nullable Drawable placeholder) {
            }

        });

Upvotes: 6

nuhkoca
nuhkoca

Reputation: 1943

Thanks all. All of your answers helped me out. I also find useful solutions with Glide's official documentation. I have switched over to Glide App Module in order to have common usage of it.

https://medium.com/@nuhkocaa/manage-all-your-glides-in-a-single-class-with-glidemodule-on-android-4856ee4983a1

Upvotes: 0

Yashwant Vadali
Yashwant Vadali

Reputation: 161

Currently, at version Glide version 4.9.0, you can set a background for Relative Layout as:-

Glide.with(MainActivity.this)
                    .load(IMAGE_URL)
                    .into(new CustomTarget<Drawable>() {
                        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
                        @Override
                        public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                            mLinearLayout.setBackground(resource);
                        }

                        @Override
                        public void onLoadCleared(@Nullable Drawable placeholder) {

                        }
                    });

Upvotes: 16

Dani
Dani

Reputation: 4131

I think the best way to achieve it's works with your own ViewTarget implementation, because this class has specific methods to be handled by Glide automatically in different scenarios.

The abstract implementation for ViewGroup (LinearLayout, RelativeLayout and so on).

public abstract class ViewGroupTarget<Z> extends ViewTarget<ViewGroup, Z> implements GlideAnimation.ViewAdapter {

    public ViewGroupTarget(ViewGroup view) {
        super(view);
    }

    /**
     * Returns the current {@link android.graphics.drawable.Drawable} being displayed in the view using
     * {@link android.widget.ImageView#getDrawable()}.
     */
    @Override
    public Drawable getCurrentDrawable() {
        return view.getBackground();
    }

    /**
     * Sets the given {@link android.graphics.drawable.Drawable} on the view using
     * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
     *
     * @param drawable {@inheritDoc}
     */
    @Override
    public void setDrawable(Drawable drawable) {
        view.setBackground(drawable);
    }

    /**
     * Sets the given {@link android.graphics.drawable.Drawable} on the view using
     * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
     *
     * @param placeholder {@inheritDoc}
     */
    @Override
    public void onLoadStarted(Drawable placeholder) {
        view.setBackground(placeholder);
    }

    /**
     * Sets the given {@link android.graphics.drawable.Drawable} on the view using
     * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
     *
     * @param errorDrawable {@inheritDoc}
     */
    @Override
    public void onLoadFailed(Exception e, Drawable errorDrawable) {
        view.setBackground(errorDrawable);
    }

    /**
     * Sets the given {@link android.graphics.drawable.Drawable} on the view using
     * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.
     *
     * @param placeholder {@inheritDoc}
     */
    @Override
    public void onLoadCleared(Drawable placeholder) {
        view.setBackground(placeholder);
    }

    @Override
    public void onResourceReady(Z resource, GlideAnimation<? super Z> glideAnimation) {

        this.setResource(resource);
    }

    protected abstract void setResource(Z resource);

}

The specific implementation, in this case for LinearLayout.

public class LinearLayoutTarget extends ViewGroupTarget<Bitmap> {

    private Context context;

    public LinearLayoutTarget(Context context, LinearLayout linearLayout) {

        super(linearLayout);

        this.context = context;
    }

    /**
     * Sets the {@link android.graphics.Bitmap} on the view using
     * {@link android.widget.ImageView#setImageBitmap(android.graphics.Bitmap)}.
     *
     * @param resource The bitmap to display.
     */
    @Override
    protected void setResource(Bitmap resource) {

        view.setBackground(new BitmapDrawable(context.getResources(), resource));
    }

}

To work with.

Glide.with(this.getApplicationContext())
                .load(R.drawable.your_image)
                .asBitmap()
                .into(new LinearLayoutTarget(this.getApplicationContext(), (LinearLayout) yourLinearLayoutInstanceHere));

Or even more simple working without Bitmap.

The specific implementation.

public class LinearLayoutTarget extends ViewGroupTarget<Drawable> {

    public LinearLayoutTarget(LinearLayout linearLayout) {

        super(linearLayout);
    }

    /**
     * Sets the {@link android.graphics.Bitmap} on the view using
     * {@link android.widget.ImageView#setImageBitmap(android.graphics.Bitmap)}.
     *
     * @param resource The bitmap to display.
     */
    @Override
    protected void setResource(Drawable resource) {

        view.setBackground(resource);
    }

}

To work with.

Glide.with(this.getApplicationContext())
                .load(R.drawable.your_image)
                .into(new LinearLayoutTarget((LinearLayout) yourLinearLayoutInstanceHere));

Upvotes: 9

Related Questions