Glide Tutorial for Android: Getting Started
In this Glide Tutorial, you’ll learn how to use Glide to create a photo app that displays pictures to your users with different filters. By Meng Taing.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Glide Tutorial for Android: Getting Started
25 mins
- Getting Started
- Adding Permission and Dependencies
- Photo Source
- Loading a Photo Gallery
- Loading a Profile Picture
- Editing Photos with More Transformations
- Clearing the Cache
- Displaying the Loading Progress Bar
- Adding Glide Annotation and OkHttp Integration
- Creating ResponseProgressListener
- Creating UIonProgressListener
- Creating DispatchingProgressManager
- Listening to Progress in the ResponseBody of OkHttp
- Extending a Glide Module
- Wiring Everything Together
- Applying ProgressListener to PhotoViewHolder
- Where to Go From Here?
Extending a Glide Module
Create a new class named ProgressAppGlideModule under the glide package with the following code:
@GlideModule //1
class ProgressAppGlideModule : AppGlideModule() {
override fun registerComponents(context: Context, glide: Glide, registry: Registry) { //2
super.registerComponents(context, glide, registry)
val client = OkHttpClient.Builder()
.addNetworkInterceptor { chain -> //3
val request = chain.request()
val response = chain.proceed(request)
val listener = DispatchingProgressManager() //4
response.newBuilder()
.body(OkHttpProgressResponseBody(request.url(), response.body()!!, listener)) //5
.build()
}
.build()
glide.registry.replace(GlideUrl::class.java, InputStream::class.java, OkHttpUrlLoader.Factory(client)) //6
}
}
- Remember the dependency you added with
kapt
in the build.gradle file earlier? This is where you need it. - The only thing you need to do here is to override the
registerComponents(...)
and replace it with your ownOkHttpClient
. - Add an
Interceptor
to your ownOkHttpClient
. - This is where you create your
DispatchingProgressManager
instance. - This is where you provide your own
OkHttpProgressResponseBody
with theDispatchingProgressManager
instance. - Glide provides a
OkHttpUrlLoader.Factory
class for you to conveniently replace Glide's default networking library.
Wiring Everything Together
This is the final class you've to create under the glide package. You need a class to associate the ImageView
with its ProgressBar
. Create a GlideImageLoader
class:
class GlideImageLoader(
private val mImageView: ImageView?,
private val mProgressBar: ProgressBar?) { //1
fun load(url: String?, options: RequestOptions?) { //2
if (options == null) return
onConnecting() //3
DispatchingProgressManager.expect(url, object : UIonProgressListener { //4
override val granularityPercentage: Float //5
get() = 1.0f
override fun onProgress(bytesRead: Long, expectedLength: Long) {
if (mProgressBar != null) {
mProgressBar.progress = (100 * bytesRead / expectedLength).toInt() //6
}
}
})
Glide.with(mImageView!!.context) //7
.load(url)
.apply(options) //8
.listener(object : RequestListener<Drawable> { //9
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?,
isFirstResource: Boolean): Boolean {
DispatchingProgressManager.forget(url)
onFinished()
return false
}
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?,
dataSource: DataSource?, isFirstResource: Boolean): Boolean {
DispatchingProgressManager.forget(url)
onFinished()
return false
}
})
.into(mImageView)
}
private fun onConnecting() {
if (mProgressBar != null) mProgressBar.visibility = View.VISIBLE
}
private fun onFinished() {
if (mProgressBar != null && mImageView != null) {
mProgressBar.visibility = View.GONE
mImageView.visibility = View.VISIBLE
}
}
}
If you receive an error saying that "There are no type arguments expected for annotation class target," add the com.bumptech.glide.request.target.Target
dependency at the top of your class.
Step by step:
- Provide
ImageView
and itsProgressBar
to yourGlideImageLoader
constructor. - Expose a
load(url: String?, options: RequestOptions?)
because you'll load the URL with Glide internally. You still acceptRequestOption
for transformations, placeholders, etc. - When starting to load the image, make sure the
ProgressBar
is visible. - This is where you call the
expect(...)
to store the progress and reference to the listener you initialize here. - Set
granularityPercentage
with a value of 1 so that the listener will be called for every minimum one percent of the progress changed. - Update the
ProgressBar
's progress. - Call Glide to load an image here internally.
- Apply the
options
from the parameters. - Glide exposes a resource listener so that you can perform extra actions if the image resource is loaded with success or failure. In either case, you want your
ProgressAppGlideModule
to forget the URL, hide theProgressBar
and make sure theImageView
is visible.
Up to this point, your glide package should have all the classes as shown in the screenshot below:
Applying ProgressListener to PhotoViewHolder
If you observed the layout of EditPhotoActivity closely, you might have seen a ProgressBar
ready for you to manipulate.
Go back to EditPhotoActivity.kt. Right below the class declaration of EditPhotoActivity
, create a private instance of GlideImageLoader
as follows:
private var glideImageLoader: GlideImageLoader? = null
You can only initialize glideImageLoader
inside onCreate
right below setContentView(R.layout.activity_edit_photo)
:
glideImageLoader = GlideImageLoader(ivPhoto, progressBar)
Replace the code where you loaded the image URL with Glide before the closing bracket of applyFilters(progress: Int, photoUrl: String?)
with the code below:
glideImageLoader?.load(
photoUrl,
RequestOptions()
.override(500, 500)
.transform(
CenterCrop(),
BlurTransformation(blurValue),
ContrastFilterTransformation(contrastValue),
VignetteFilterTransformation(
PointF(0.5f, 0.5f),
floatArrayOf(0f, 0f, 0f),
0f,
vignetteValue))
.diskCacheStrategy(DiskCacheStrategy.DATA)
.placeholder(ivPhoto.drawable))
This is similar to what you did earlier. Instead of calling Glide.with(...).load(...).into(...)
directly, now you use your own glideImageLoader
to do the job. You can still pass all the request options with the default Glide loader.
Run the app to check whether the ProgressBar
in the EditPhotoActivity is updating as the photo is being loaded. If you don't see a ProgressBar
, the photo is probably loaded from the cache. Click the Clear Cache menu item on the MainActivity screen, and then click on the photo you want to edit again:
Where to Go From Here?
You've just built your very own Instagram with Glide! You can extend the functionality of the app by allowing users to share the edited photos on social media or save to the device storage. There are many other cool things you can do with Glide such as loading GIFs and applying crossfade transitions. Keep Gliding!
Download the final project by clicking the Download Materials button at the top or bottom of this tutorial.
If you're curious about Glide's performance compared with other image loading libraries such as Picasso or Fresco, you can build a simple app that shows the downloading duration of each library. By now, you should know how to use Glide’s Request Listener and be ready to give it a try.
If you have any questions or comments, please join the forum discussion.