Android - Loading and Caching Images with Fresco

    In Facebook app, images loading is performed by Fresco. This is a library written by Facebook developers. It is a powerful system for displaying images in Android applications. It takes care of image loading and display so you don't have to. It's also caching images in memory or internal storage, so we do not have to submit the requests to load images multiple times.
    In this post, I will present an overview of it. Hope everyone can grasp the essentials.
    DEMO VIDEO:

Import Fresco to Android Project

    In order to use it, please add this dependency to your local build.gradle (usually in 'app' module):
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.facebook.fresco:fresco:0.7.0' //fresco dependency
 }

Customizing Images view in xml

    Especially, beside loading online images feature, Fresco also allows users to create multiple image shape like circular image, round corner image and many specially features...
    With SimpleDraweeView class, we can create them by corresponding attributes. For example, this xml can be used to make the circular ImageView through fresco:roundAsCircle:

<com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/circle"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:roundAsCircle="true" />
    And output maybe like this:
    A normal ImageView with the place holder drawable (the default image when loading process error or happening:

<com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/sdv_image"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:placeholderImage="@mipmap/ic_launcher" />
    The default output:
    A round corner ImageView:

<com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/round_border"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:placeholderImage="@mipmap/ic_launcher"
            fresco:roundBottomLeft="true"
            fresco:roundBottomRight="true"
            fresco:roundWithOverlayColor="@color/green"
            fresco:roundedCornerRadius="20dp"
            fresco:roundingBorderColor="@color/red"
            fresco:roundingBorderWidth="4dp" />
    And we have this result:
    Moreover, we also can make an ImageView with progressbar when loading, a retry image which can be invoke reloading when clicked,...A full custom should be like this code:
<com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/full_custom_image"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:actualImageScaleType="focusCrop"
            fresco:backgroundImage="@color/colorPrimary"
            fresco:fadeDuration="300"
            fresco:failureImage="@drawable/error"
            fresco:failureImageScaleType="centerInside"
            fresco:placeholderImage="@mipmap/ic_launcher"
            fresco:placeholderImageScaleType="fitCenter"
            fresco:pressedStateOverlayImage="@color/red"
            fresco:progressBarAutoRotateInterval="1000"
            fresco:progressBarImage="@drawable/loading"
            fresco:progressBarImageScaleType="centerInside"
            fresco:retryImage="@drawable/retry"
            fresco:retryImageScaleType="centerCrop"
            fresco:roundAsCircle="false"
            fresco:roundBottomLeft="false"
            fresco:roundBottomRight="true"
            fresco:roundTopLeft="true"
            fresco:roundTopRight="false"
            fresco:roundWithOverlayColor="@color/colorPrimaryDark"
            fresco:roundedCornerRadius="1dp"
            fresco:roundingBorderColor="@color/colorAccent"
            fresco:roundingBorderWidth="2dp" />

Initializing in programmatically code

    In the activities of fragment code, we will set up the loading data process. Remember to initializing Fresco first by this line in the activity onCreate() method:
Fresco.initialize(this);
    Important Note: Always invoking this code before calling setContentView().
    When loading image from URL, just call setImageURI(), Fresco will do whole loading data process:
roundBorderImage.setImageURI(imageUri);

Full project code

    In this simple project, there are only one Activity which loading image data from URL, this is full code: MainActivity.java

package info.devexchanges.fresco;

import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.view.SimpleDraweeView;

public class MainActivity extends AppCompatActivity {

    private Button button;
    private SimpleDraweeView sdvImage;
    private SimpleDraweeView roundBorderImage;
    private SimpleDraweeView circleImage;
    private SimpleDraweeView fullCustomImage;

    private void findViews() {
        button = (Button) findViewById(R.id.button);
        sdvImage = (SimpleDraweeView) findViewById(R.id.sdv_image);
        roundBorderImage = (SimpleDraweeView) findViewById(R.id.round_border);
        circleImage = (SimpleDraweeView) findViewById(R.id.circle);
        fullCustomImage = (SimpleDraweeView) findViewById(R.id.full_custom_image);
    }

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

        final Uri imageUri = Uri.parse("https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpfvidFNRG-3nj8ZzFJNC4_AV3pD8p6TkObjdKQMDFZfjfVd9i7fUpF2JaRgulwcDnreFubB73YKy2JBu5K_wgdaxlI3iKqN7fpuEI6EGp-hg83UC26SWHLwBlAkjcP1oGQhw8KreBEqVO/w140-h105-p/fresh_green_grass_bokeh-wallpaper-1024x768.jpg");
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sdvImage.setImageURI(imageUri);
                roundBorderImage.setImageURI(imageUri);
                circleImage.setImageURI(imageUri);
                fullCustomImage.setImageURI(imageUri);
            }
        });
    }
}
    And it's layout, which contains all custom image shapes: activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        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">

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Loading Images From URL" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="Simple Image"
            android:textStyle="bold" />

        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/sdv_image"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:placeholderImage="@mipmap/ic_launcher" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:text="Round Corner Image"
            android:textStyle="bold" />

        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/round_border"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:placeholderImage="@mipmap/ic_launcher"
            fresco:roundBottomLeft="true"
            fresco:roundBottomRight="true"
            fresco:roundWithOverlayColor="@color/green"
            fresco:roundedCornerRadius="20dp"
            fresco:roundingBorderColor="@color/red"
            fresco:roundingBorderWidth="4dp" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:text="Circle Image"
            android:textStyle="bold" />

        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/circle"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:roundAsCircle="true" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:text="Full Customization Image"
            android:textStyle="bold" />

        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/full_custom_image"
            android:layout_width="130dp"
            android:layout_height="130dp"
            android:layout_gravity="center"
            fresco:actualImageScaleType="focusCrop"
            fresco:backgroundImage="@color/colorPrimary"
            fresco:fadeDuration="300"
            fresco:failureImage="@drawable/error"
            fresco:failureImageScaleType="centerInside"
            fresco:placeholderImage="@mipmap/ic_launcher"
            fresco:placeholderImageScaleType="fitCenter"
            fresco:pressedStateOverlayImage="@color/red"
            fresco:progressBarAutoRotateInterval="1000"
            fresco:progressBarImage="@drawable/loading"
            fresco:progressBarImageScaleType="centerInside"
            fresco:retryImage="@drawable/retry"
            fresco:retryImageScaleType="centerCrop"
            fresco:roundAsCircle="false"
            fresco:roundBottomLeft="false"
            fresco:roundBottomRight="true"
            fresco:roundTopLeft="true"
            fresco:roundTopRight="false"
            fresco:roundWithOverlayColor="@color/colorPrimaryDark"
            fresco:roundedCornerRadius="1dp"
            fresco:roundingBorderColor="@color/colorAccent"
            fresco:roundingBorderWidth="2dp" />

    </LinearLayout>
</ScrollView>
    Important Note:
  • Never forget Internet permission in AndroidManifest.xml when working with online data:
    <uses-permission android:name="android.permission.INTERNET"/>
    
  • In xml files, you must declare the android:layout_width and android:layout_height of SimpleDraweeView with real dimension value, instead of match_parent or wrap_content.

More information

    Visiting Fresco official document, you can find out more features of this powerful library like loading image form sd card, image pipeline,...(another advantage of Fresco is a good document). In this post, I've just introduce the basic features. Finally, you can download my project from @Github by clicking the button below.


Share


Previous post
« Prev Post
Next post
Next Post »