Hot questions for Using Glide in android layout

Top 10 Java Open Source / Glide / android layout

Question:

I want to use the Glide Android library to download an image and show in ImageView.

In the previous version we used:

Glide.with(mContext).load(imgUrl)
                .thumbnail(0.5f)
                .placeholder(R.drawable.PLACEHOLDER_IMAGE_NAME)
                .error(R.drawable.ERROR_IMAGE_NAME)
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(imageView);

But I have seen Glide documentation:

it says use GlideApp.with() instead Glide.with()

My concern is a missing placeholder, error, GlideApp, and other options.

I am using

 compile 'com.github.bumptech.glide:glide:4.0.0'

Where am I doing wrong? With reference to here.

How has GlideApp.with() been used?

The API is generated in the same package as the AppGlideModule and is named GlideApp by default. Applications can use the API by starting all loads with GlideApp.with() instead of Glide.with():

GlideApp.with(fragment)
   .load(myUrl)
   .placeholder(placeholder)
   .fitCenter()
   .into(imageView);

Answer:

Try using RequestOptions:

RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.ic_placeholder);
requestOptions.error(R.drawable.ic_error);

Glide.with(context)
     .setDefaultRequestOptions(requestOptions)
     .load(url).into(holder.imageView);

EDIT

If .setDefaultRequestOptions(requestOptions) does not work, use .apply(requestOptions):

Glide.with(MainActivity.this)
            .load(url)
            .apply(requestOptions)
            .into(imageview);
 // or this
 Glide.with(MainActivity.this)
            .load(url)
            .apply(new RequestOptions().placeholder(R.drawable.booked_circle).error(R.drawable.booked_circle))
            .into(imageview);

 // or this
 Glide.with(MainActivity.this)
            .load(url)
            .apply(RequestOptions.placeholderOf(R.drawable.booked_circle).error(R.drawable.))
            .into(imageview);

EDIT 2 Bonus

Here are some other changes in Glide-4

  • How to use requestOptions.circleCropTransform();
  • How to use Cross fades()
  • How to use GlideDrawableImageViewTarget in Glide-4
  • How to use GifDrawable as target parameter

Question:

I want to make an image fit into my image view. I am loading the image programmatically using Glide. It does load the image but does not stretch it to fit my entire image view. It leaves blank spaces on both sides like this

I want to display my entire image without cropping so I can't use

android:scaleType="centerCrop"

There's a way to fit the entire image into my image view by using

android:background="@drawable/image"

It stretches my image to fit the entire image view. But how can I achieve the same if i am loading the image using Glide ?


Answer:

I finally got the answer to it. Simply use

android:scaleType="fitXY"

in the xml ImageView tag like this and load image using Glide or BitmapFactory without using any scaleType attribute there.

<ImageView
 android:id="@+id/image_view"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:scaleType="fitXY"/>

Load Image to the image View

Glide.with(this).load(imageUrl).into((ImageView)findViewById(R.id.image_view));

Question:

I am developing an app that show all album cover images of the songs. So I am using glide for loading and caching images and to avoid OutofMemoryError but I still get that error:

11-11 11:05:55.866 11120-11120/com.xrobot.andrew.musicalbumsE/AndroidRuntime﹕ FATAL EXCEPTION: main Process: com.xrobot.andrew.musicalbums, PID: 11120 java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available 

This is my getView in the AlbumAdapter:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    RelativeLayout albumsLay = (RelativeLayout)songInf.inflate
            (R.layout.album_layout, parent, false);
    ImageView coverView = (ImageView)albumsLay.findViewById(R.id.song_cover);

    //get song using position
    Song currSong = songs.get(position);

    if (Drawable.createFromPath(currSong.getCover()) != null) {
        Drawable img = Drawable.createFromPath(currSong.getCover());
        Glide.with(mContext).load("").placeholder(img).override(50,50).into(coverView);
    }

    albumsLay.setTag(position);
    return albumsLay;
}

Answer:

Try using Glide directly with the image path:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    RelativeLayout albumsLay = (RelativeLayout)songInf.inflate
            (R.layout.album_layout, parent, false);
    ImageView coverView = (ImageView)albumsLay.findViewById(R.id.song_cover);

    //get song using position
    Song currSong = songs.get(position);

    // If you are sure currSong.getCover() exists you can remove the if statement
    if(new File(currSong.getCover().exists))
        Glide.with(mContext).load(currSong.getCover()).override(50,50).into(coverView);


    albumsLay.setTag(position);
    return albumsLay;
}

And you could also use a holder for the view. This would reduce the memory usage:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
     CoverHolder holder = null;
     if (convertView == null) {
         convertView = mInflater.inflate(R.layout.album_layout, null);
         holder = new CoverHolder();
         holder.coverView = (ImageView)convertView.findViewById(R.id.song_cover);
         convertView.setTag(holder);
     } else {
         holder = (CoverHolder)convertView.getTag();
     }
    Glide.with(mContext).load(currSong.getCover()).override(50,50).into(holder.coverView);
    return convertView;
}

// The holder
public static class CoverHolder{
    public ImageView coverView;
}

Still, if you really need performance on a huge list. You can take a look at the RecyclerView here.

Question:

I have a feed that sends me the list of logos

{
  "logos": {
    "GoogleLogo": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEC8Plg0onmk5-0lHzN74023FJaH_N_4prUSlBBaUR9FqmjbfVhA"
  }
}

There are around 30 Logos that this feed sends me.

What i want to do is to to hit this service when user launches the app for the first time, and cache all the images by using Glide.

So in app whenever i use following method, it won't hit the service, and display the images right away to user.

  GlideApp
    .with(myFragment)
    .load(url)
    .centerCrop()
    .placeholder(R.drawable.loading_spinner)
    .into(myImageView);

I will be creating a HashMap<String, String> that will have logo name as key and its URL as value.

My Question is that is there any method available in Glide which can be used to cache images without displaying them.


Answer:

Yes using FutureTarget you can load image in Background.

start Intent Service and load images in onHandleIntent method. Like,

String data = intent.getStringExtra("data");
    try {
        JSONObject jsonObject = new JSONObject(data);
        JSONArray jsonArray = jsonObject.getJSONObject("data").getJSONArray("res");
        for (int i = 0; i < jsonArray.length(); i++) {
            if (common.getNetworkType().equalsIgnoreCase("-")) {
                stopSelf();
                break;
            } else {
                JSONObject jObj = jsonArray.getJSONObject(i);
                FutureTarget<File> future = Glide.with(this).load(common.completeURL(jObj.getString("AvatarImage"))).downloadOnly(400, 400);
                try {
                    future.get();
                    break;
                } catch (InterruptedException e) {
                    stopSelf();
                    break;
                } catch (ExecutionException e) {
                    stopSelf();
                    break;
                }
            }

        }
    } catch (Exception e) {
        stopSelf();
        logger.w(TAG, "onHandleIntent: ", e);
    }

Question:

In one of my Android layouts, one of the ImageView is "optional", meaning there isn't always a url for the src. I'm following the MVVM pattern, and I want to show the ImageView if there is a URL, and not show it if the URL is null.

First of all, I know this can be done using two separate, almost identical layout resource files. But I don't want to write that much code, especially since the only difference between these two layouts, is the fact that this thumbnail image may or may not exist (is null).

    <ImageView
        android:id="@+id/image_topic_creator_thumbnail"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:onClick="@{viewModel::getProfileOfCurrentTopicCreator}"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_topic_body"
        app:userThumbnailUrl="@{viewModel.currentTopic.creator.thumbnailUrl}" />

And here is the code from the ViewModel:

    // circular image
@BindingAdapter({"userThumbnailUrl"})
public static void setUserThumbnailUrl(ImageView view, String url) {
    RequestOptions options = new RequestOptions()
            .circleCrop()
            .placeholder(R.drawable.user_thumbnail_placeholder)
            .error(R.drawable.user_thumbnail_placeholder)
            .priority(Priority.LOW);
    Glide.with(view.getContext())
            .load(url)
            .apply(options)
            .into(view);
}

In this case, app:userThumbnailUrl can't take in a null or empty string because that would cause an error in Glide. I can implement the logic in the ViewModel to check to see if the url is null or empty, then don't use Glide, but then what do I return as a result? Do I just not do anything when the url is null? Wouldn't that cause an error in the ImageView and cause things to crash in the app?


Answer:

Your ImageView is by default visible. Have the default be invisible, and then show it if the url exists.

  <ImageView
        android:id="@+id/image_topic_creator_thumbnail"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:visible="gone" //set invisible here here
        android:onClick="@{viewModel::getProfileOfCurrentTopicCreator}"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_topic_body"
        app:userThumbnailUrl="@{viewModel.currentTopic.creator.thumbnailUrl}" />




@BindingAdapter({"userThumbnailUrl"})
    public static void setUserThumbnailUrl(ImageView view, String url) {

        if (url != "") {
            RequestOptions options = new RequestOptions()
                .circleCrop()
                .placeholder(R.drawable.user_thumbnail_placeholder)
                .error(R.drawable.user_thumbnail_placeholder)
                .priority(Priority.LOW);
            Glide.with(view.getContext())
                .load(url)
                .apply(options)
                .into(view);
        }
    }