Android Core

Using DataBinding with Glide in Android

In this post on databinding, we’ll take a look at how to load images using databinding with glide in an imageview.

Let me begin by saying that you don’t need custom imageviews for this. Using binding adapter to declare a custom attribute, we can easily load a remote image into imageview with databinding.

I’ll be creating a sample project for this. It’ll have an image at the center of the screen. I’ll be loading the image from my about page.

So, let’s start!

Adding DataBinding

To include databinding in your project, go to build.gradle and add the following lines:

1
2
3
dataBinding {
    enabled = true
}

Also, we’ll need to include the dependency for glide library:

1
2
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'

Now, sync the project and you’re good to go. It’s as simple as that.

Creating the Layout

Now let’s create the layout. We’ll just be having an imageview at the center, with a textview below it

Here’s the activity_main.xml layout file:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="utf-8"?>
<layout>
 
    <data>
 
        <variable
            name="user"
            type="com.example.databindingexample.User" />
    </data>
 
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
 
        <TextView
            android:id="@+id/tv_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:text="This is sample text" />
 
 
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_name" />
 
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Modelling our Data

Nothing fancy. For the sake of this tutorial, we’ll just create a user object which’ll have a name and a profile image url. Here’s how it looks:

1
2
3
4
class User {
    var name: String = ""
}

Connecting xml and Kotlin

How will the layout get it’s user variable from? For this, we’ll need to assign the object to the layout through code.

In the MainActivity.kt file, we’ll be attaching our xml and kotlin files. Here’s our MainActivity.kt file:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.example.databindingexample
 
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.databinding.DataBindingUtil
import com.example.databindingexample.databinding.ActivityMainBinding
 
class MainActivity : AppCompatActivity() {
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        val user = User()
        user.name = "Ayusch"
        binding.user = user
    }
}

First, we set our contentView by using DataBindingUtils which is provided by databinding library. It needs a generic type. In our case it will be ActivityMainBinding. Don’t panic if you see all reds for that. That’s a generated file and you’ll need to build your project once to get it.

Using DataBinding with ImageView

Now this is where the magic happens. Here we’ll see how to load an image into our imageview using databinding with glide.

First of all, we’ll need to create a BindingAdapter which’ll have the custom logic to load our image using glide. It’s a simple method with a BindingAdapter annotation and an attribute(s)  to bind with.

Let’s see how this works. In our user class we’ll create a public static method loadImage. It’ll take two parameters. First, the view itself and second the URL of the image.

Remember: The method needs to be public static and the first parameter will be the view. This is very important.

1
2
3
4
5
6
7
8
9
companion object {
    @JvmStatic
    @BindingAdapter("profileImage")
    fun loadImage(view: ImageView, profileImage: String) {
        Glide.with(view.context)
            .load(profileImage)
            .into(view)
    }
}

Then, we can load the image into imageview using Glide. We’re all familiar with that.

Now to use databinding with imageview to load images, we’ll need to tell the imageview to use our custom adapter. This’ll happen in our activity_main.xml layout file. Add this line to your imageview.

1
app:profileImage="@{user.profileImage}"

Databinding ImageView with Placeholder

We can also accept multiple arguments in our bindingadapter. For example, one may need to load an error image, or a placeholder while our image loads.

We’ll pass a list of attributes to our bindingadapter to bind to. We’ll need to add some code to check if an error occurred and then set the error image. Here’s how it looks:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
companion object {
        @JvmStatic
        @BindingAdapter(value = ["profileImage", "error"], requireAll = false)
        fun loadImage(view: ImageView, profileImage: String, error: Int) {
            Glide.with(view.context)
                .load(profileImage)
                .listener(object : RequestListener<Drawable> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<Drawable>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        view.setImageResource(error)
                        return true
                    }
 
                    override fun onResourceReady(
                        resource: Drawable?,
                        model: Any?,
                        target: Target<Drawable>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                        view.setImageDrawable(resource)
                        return true
                    }
 
                })
                .into(view)
        }
    }

Note that we’ve set requireAll to false. This ensures that this adapter is used even if one of the attributes is not set in xml. Omit this if you want to ensure this gets called only if all attributes are provided.

Now in our imageView layout, we can provide a resource for the error state.

1
app:error="@{user.errorImage}"

With this we end our tutorial on databinding with glide. Hope you liked it.

Conclusion

Databinding can be used with many other libraries just as Glide, Picasso, Fresco etc. All you need to do is alter your binding adapter’s logic.

*Important*: Join the AndroidVille SLACK  workspace for mobile developers where people share their learnings about everything latest in Tech, especially in Android Development, RxJava, Kotlin, Flutter, and mobile development in general.

Click on this link to join the workspace. It’s absolutely free!

Related

Published on Java Code Geeks with permission by Ayusch Jain, partner at our JCG program. See the original article here: Using DataBinding with Glide in Android

Opinions expressed by Java Code Geeks contributors are their own.

Ayusch Jain

Ayusch is a Software Engineer currently working in Android Development. He's worked long enough that he's transformed into an Android himself :P. Additionally, he also maintains a community of Android developers called: AndroidVille and writes about Android on his website: https://ayusch.com
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Elena Gillbert
4 years ago

Hi…
I’m elena gillbert.Databinding can be used with many other libraries just as Glide, Picasso, Fresco etc. All you need to do is alter your binding adapter’s logic.

*Important*: Join the AndroidVille SLACK workspace for mobile developers where people share their learnings about everything latest in Tech, especially in Android Development, RxJava, Kotlin, Flutter, and mobile development in general.

ramesh
4 years ago
Reply to  Elena Gillbert

Hey i have used kotlin synthetic binding a new way for data binding https://www.youtube.com/watch?v=G1ZInI03OA8

Back to top button