Combining DataBinding and Picasso: Loading Image from Url in Android

    In the previous post, you've learned some basic features of Data Binding Library - a mechanism to make a bridge between Presentation layer and Model layer. Today, we will take a look at Image loading with data binding. I will use Picasso - a powerful library to load Bitmap from an url.

    In order to understanding this post, you should take a glance to:
  • My previous post about "Getting Started with Data Binding" to understand how to integrate Data Binding library and how to use it in layout file.
  • My previous post about Picasso to learn how to use this library in your project.
    This is your app-level build.gradle file after add Picasso dependency and declared data binding:
apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.2"
    defaultConfig {
        applicationId "info.devexchanges.picassodatabinding"
        minSdkVersion 14
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    dataBinding {
        enabled = true
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.2.0'
    compile 'com.squareup.picasso:picasso:2.5.2'
}
    Now, I will make a project which provide the way to load Bitmap image from url string and show to the ImageView after click a Button.

Create a POJO class

    Define a POJO class extended from BaseObservable like previous project with some variables and getters/setters:
Cat.java
package info.devexchanges.picassodatabinding;

import android.databinding.BaseObservable;
import android.databinding.Bindable;

public class Cat extends BaseObservable {

    private String name;
    private String imageUrl;

    public Cat(String name, String imageUrl) {
        this.name = name;
        this.imageUrl = imageUrl;
    }

    @Bindable
    public String getName() {
        return name;
    }

    @Bindable
    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(info.devexchanges.picassodatabinding.BR.name);
    }

    @Bindable
    public String getImageUrl() {
        return imageUrl;
    }

    @Bindable
    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
        notifyPropertyChanged(info.devexchanges.picassodatabinding.BR.imageUrl);
    }
}
    When dealing with third party libraries along with Data Binding, we require binding between those libraries. So we will create a class which first bind ImageView with Picasso and ImageView with Data Binding.
    Create a class called ImageBindingAdapter and put this code:
ImageBindingAdapter.java
package info.devexchanges.picassodatabinding;

import android.databinding.BindingAdapter;
import android.widget.ImageView;

import com.squareup.picasso.Picasso;

public class ImageBindingAdapter {

    @BindingAdapter({"bind:imageUrl"})
    public static void loadImage(ImageView imageView, String url) {
        if (!url.equals("")) {
            Picasso.with(imageView.getContext()).load(url).resize(200, 200).into(imageView);
        }
    }
}
    Here if you noticed, we used @BindingAdapter({"bind:imageUrl"}). This code tells Data Binding library that this is custom setter which you can get in layout with property tag named imageUrl. Lets use that imageUrl in our layout file.

Defining activity layout (XML) file

    Your main activity layout is look like this:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <import type="android.view.View" />

        <variable
            name="cat"
            type="info.devexchanges.picassodatabinding.Cat" />

        <variable
            name="handlers"
            type="info.devexchanges.picassodatabinding.MainActivity.OnClickHandler" />
    </data>

    <LinearLayout
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="info.devexchanges.picassodatabinding.MainActivity">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Cat Name:" />

            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="@{cat.name}" />
        </LinearLayout>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Cat Image:" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:contentDescription="@null"
            app:imageUrl="@{cat.imageUrl}" />

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/activity_horizontal_margin"
            android:onClick="@{handlers.onUpdateCat}"
            android:text="Load Image" />
    </LinearLayout>
</layout>
    As you can see, provide which property of your POJO class will be used with app:imageUrl of ImageView. In this case it is cat.imageUrl.

Activity programmatically code

    There is nothing special in activity Java code, binding some "default data" like previous project and after click the Button, TextView will be updated and app will load an image bitmap from the url:
MainActivity.java
package info.devexchanges.picassodatabinding;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

import info.devexchanges.picassodatabinding.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    private Cat cat;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        cat = new Cat("Tom", "");
        binding.setCat(cat);

        OnClickHandler handlers = new OnClickHandler();
        binding.setHandlers(handlers);
    }

    public class OnClickHandler {
        public void onUpdateCat(View view) {
            cat.setName("Super Tom");
            cat.setImageUrl("http://i.imgur.com/6zgawxz.jpg");
            Toast.makeText(MainActivity.this, "Cat name updated, loading image...", Toast.LENGTH_SHORT).show();
        }
    }
}

Running application

    Before running app, make sure you provide Internet permission in AndroidManifest.xml for your app because it load data (bitmap) from an url:
<uses-permission android:name="android.permission.INTERNET"/>
You'll have this output:

Conclusions

    Through this post, I hope that you've learned an another features of data binding library: loading online data by combining wit Picasso. You also can try with another libraries like UniversalImageLoader, Glide,... Finally, you can take my project from @Github.
    Read more:

Share


Previous post
« Prev Post
Next post
Next Post »