Introduction

Fresco is a powerful system for displaying images in Android applications.

Fresco takes care of image loading and display, so you don’t have to. It will load images from the network, local storage, or local resources, and display a placeholder until the image has arrived. It has two levels of cache; one in memory and another in internal storage.

Import

The line below is supposed to added to the build.gradle of your module.

compile 'com.facebook.fresco:fresco:0.14.1'

Simple sample

Here I use SimpleDraweeView first to see what Fresco can do.

import namespace

First of all, import the namespace fresco in xml:

xmlns:fresco="http://schemas.android.com/apk/res-auto"

use widget

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/sdv_fresco"
    android:layout_width="300dp"
    android:layout_height="300dp"/>

It’s required to set layout_width and layout_height with specific number, and wrap_content is not permitted here. It is because when the download completes, the layout will be re-adjusted, and if the size of placeholderImage dismatches the final image, the transition will be very sharp.

You can use wrap_content, only when you want to display the image in a specific aspect ratio.

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/sdv_fresco"
    android:layout_width="300dp"
    android:layout_height="wrap_content"
    fresco:viewAspectRatio="1.5"/>		<!-- it means width/height=1.5 -->

initalize Fresco

In the method onCreate, before the statement setContentView(), add:

Fresco.initialize(this);

specify uri

Fresco accepts uri in large range of formats, but make sure it’s an absolute uri.

mSimpleDraweeView = (SimpleDraweeView) findViewById(R.id.sdv_fresco);
String url = "http://urlc.cn/XR5hy3";
mSimpleDraweeView.setImageURI(url);

Now run your app and see what happen!

Polish widget

static way

You can do it in a static way, in xml file.

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/sdv_fresco"			
    android:layout_width="300dp"
    android:layout_height="300dp"
    fresco:fadeDuration="3000"
    fresco:placeholderImage="@drawable/icon_retry"
    fresco:roundTopLeft="false"
    fresco:roundedCornerRadius="20dp"/>

See more attributes in official document.

dynamic way

You can do it in a dynamic way, in java file, it relys on GenericDraweeHierarchy.

GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources());
GenericDraweeHierarchy hierarchy = builder
        .setFadeDuration(1000)
        .setPlaceholderImage(R.drawable.icon_loading)
        .build();
mSimpleDraweeView.setHierarchy(hierarchy);

outcome

DraweeController

DraweeHierarchy can modify how and what the widget displays, like setting placeholder, setting fading duration, etc. DraweeController focuses on the logic of the displaying, like setting listener, uri, etc.

In another word, DraweeHierarchy controls the UI while DraweeController controls the action.

DraweeController controller = Fresco.newDraweeControllerBuilder()
        .setUri(url)
        .setOldController(mSimpleDraweeView.getController())
        .setTapToRetryEnabled(true)
        .build();
mSimpleDraweeView.setController(controller);

In fact, when we invoke method draweeView.setImageUri(), this is what happen:

public void setImageURI(Uri uri, @Nullable Object callerContext) {
	DraweeController controller = mSimpleDraweeControllerBuilder
	    .setCallerContext(callerContext)
	    .setUri(uri)
	    .setOldController(getController())
	    .build();
	setController(controller);
}

See that actually we use DraweeController here.