天天看點

圖檔加載架構之圖檔加載架構選型(一)下篇一、 Picasso分析二、Fresco的使用

阿裡P7移動網際網路架構師進階視訊(每日更新中)免費學習請點選: https://space.bilibili.com/474380680 本篇文章将通過Picasso分析、Fresco的使用來闡述圖檔加載架構選型:

一、 Picasso分析

Picasso是Square公司開源的一個Android平台上的圖檔加載架構

核心類:

Picasso:負責圖檔下載下傳、變換、緩存的管理器,當它收到一個圖檔下載下傳請求的時候,它會建立Request并送出給Dispatcher

Dispatcher: Dispatcher會尋找對應的處理器RequestHandler,并将請求與該處理器一起送出給線程池執行

圖檔加載步驟:

建立 -> 入隊 -> 執行 -> 解碼 -> 變化 -> 批處理 -> 完成 -> 分發 -> 顯示

使用

Picasso.get().load(url).into(first_img)

//加載一張圖檔 旋轉45°
Picasso.get()
        .load(URL)
        .rotate(45f)
        .placeholder(R.drawable.placeholder_disk)
        .into(imgOne);

//加載一張圖檔并設定一個回調接口
Picasso.get()
        .load(URL)
        .placeholder(R.drawable.placeholder_disk)
        .into(imgOne, new Callback() {

            @Override
            public void onSuccess() {

            }

            @Override
            public void onError(Exception e) {

            }
        });

//預加載一張圖檔
Picasso.get().load(URL).fetch();

//同步加載一張圖檔,注意隻能在子線程中調用并且Bitmap不會被緩存到記憶體裡.
new Thread() {
    @Override
    public void run() {
        try {
            final Bitmap bitmap = Picasso.get().load(URL).get();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}.start();

//加載一張圖檔旋轉并且添加一個Transformation,可以對圖檔進行各種變化處理,例如圓形頭像.
Picasso.get().load("url").rotate(10).transform(new Transformation() {
    @Override
    public Bitmap transform(Bitmap source) {
        //處理Bitmap
        return null;
    }

    @Override
    public String key() {
        return null;
    }
}).into(imgTwo);

//加載一張圖檔并按照指定尺寸以centerInside()的形式縮放.并設定加載的優先級為高.注意centerInside()或centerCrop()
//隻能同時使用一種,而且必須指定resize()或者resizeDimen();
Picasso.get().load(URL)
        .resize(400, 400)
        .centerInside()
        .priority(Picasso.Priority.HIGH)
        .into(imgTwo);

//加載一張圖檔并設定tag,可以通過tag來暫定或者繼續加載,可以用于當ListView滾動是暫定加載.停止滾動恢複加載.
Picasso.get().load(URL).tag(getContext()).into(imgTwo);
Picasso.get().pauseTag(getContext());
Picasso.get().resumeTag(getContext());
           

二、Fresco的使用

當下有很多圖檔加載架構,常見的有Glide、Fresco、Picasso等。Glide因為其體積小、緩存機制強大等優點,受到了廣大程式員的青睐;Fresco雖然體積比較大,緩存機制也沒有Glide強大,但它勝在擁有一些炫酷的效果(進度條、淡入效果)等,也有很多人在使用。今天我們就來介紹一下Fresco的使用。

1、配置環境

使用Fresco需要先在build.gradle中導入依賴:

// Fresco所需依賴
    compile 'com.facebook.fresco:fresco:0.12.0'
    // 在 API < 14 上的機器支援 WebP 時,需要添加
    compile 'com.facebook.fresco:animated-base-support:0.12.0'
    // 支援 GIF 動圖,需要添加
    compile 'com.facebook.fresco:animated-gif:0.12.0'
    // 支援 WebP (靜态圖+動圖),需要添加
    compile 'com.facebook.fresco:animated-webp:0.12.0'
    compile 'com.facebook.fresco:webpsupport:0.12.0'           

如果需要從網絡中下載下傳圖檔,則需要在AndroidManifest.xml檔案中配置網絡權限:

<uses-permission android:name="android.permission.INTERNET" />           

最後,在項目的Application中初始化Fresco:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化Fresco
        Fresco.initialize(this);
    }
}           

别忘了在AndroidManifest.xml檔案中為Application添加name屬性:

<application
        android:name=".MyApplication"
        ......
    </application>           

2、SimpleDraweeView

2.1、XML屬性

Fresco為我們提供了一個SimpleDraweeView控件,我們可以直接在這個控件中加載圖檔。Fresco在這個控件中內建了很多屬性,簡單實用。以下是SimpleDraweeView中的常用屬性:           
fresco:actualImageScaleType:實際加載的圖檔的伸縮樣式
        fresco:backgroundImage:底層圖檔資源
        fresco:fadeDuration:進度條和占位符圖檔逐漸消失、加載的圖檔逐漸顯示的時間間隔
        fresco:failureImage:加載失敗時顯示的圖檔資源
        fresco:failureImageScaleType:加載失敗時加載的圖檔的伸縮樣式
        fresco:overlayImage:在顯示的圖檔表層覆寫一張圖檔的圖檔資源
        fresco:placeholderImage:占位符圖檔資源
        fresco:placeholderImageScaleType:占位符圖檔的伸縮樣式
        fresco:progressBarAutoRotateInterval:進度條圖檔轉動周期
        fresco:progressBarImage:進度條圖檔資源
        fresco:progressBarImageScaleType:進度條圖檔的伸縮樣式
        fresco:retryImage:提示重新加載的圖檔資源
        fresco:retryImageScaleType:提示重新加載的圖檔的伸縮樣式
        fresco:roundAsCircle:将圖檔剪切成圓形
        fresco:viewAspectRatio:圖檔寬高比           

我們的XML布局檔案中的代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/id_main_sdv_sdv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        fresco:actualImageScaleType="focusCrop"
        fresco:fadeDuration="3000"
        fresco:failureImage="@mipmap/ic_launcher"
        fresco:failureImageScaleType="centerInside"
        fresco:placeholderImage="@mipmap/ic_launcher"
        fresco:placeholderImageScaleType="fitCenter"
        fresco:progressBarAutoRotateInterval="1000"
        fresco:progressBarImage="@mipmap/ic_launcher"
        fresco:progressBarImageScaleType="centerInside"
        fresco:retryImage="@mipmap/ic_launcher"
        fresco:retryImageScaleType="centerCrop"
        fresco:roundAsCircle="false"
        fresco:viewAspectRatio="1.6" />

    <Button
        android:id="@+id/id_main_btn_load"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_margin="20.0dip"
        android:text="Start Load Image" />

</RelativeLayout>           

2.2、注意事項

(1)SimpleDraweeView控件的寬高不能設定為wrap_content,隻能是match_parent、具體值或使用viewAspectRatio屬性設定寬高比。

(2)如果在一個頁面中加載多張圖檔,不要将SimpleDraweeView直接放在ScollView中,建議使用RecyclerView、ListView或GridView,因為ScrollView中的SimpleDraweeView會持有記憶體直到Activity或Fragment銷毀。

(3)使用SimpleDraweeView時,不要使用imageView中有、View中沒有的屬性。

3、架構使用

3.1、簡單使用

像TextView、Button等其他控件一樣後去到SimpleDraweeView,然後調用如下代碼即可加載網絡圖檔:

3.2、JAVA代碼設定屬性

我們可以通過GenericDraweeHierarchy,在JAVA代碼中動态的設定SimpleDraweeView控件的屬性。需要注意的是,如果在JAVA代碼中設定了屬性,那麼XML檔案中設定的屬性就都無效了。一個執行個體代碼如下:

// 代碼設定SimpleDraweeView的屬性(會覆寫XML設定的所有屬性,即在XML中有在這裡沒有的屬性都會失效)
        // 注意:一個GenericDraweeHierarchy是不能被多個SimpleDraweeView共用的
        GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())
                .setFadeDuration(3000)
                .setPlaceholderImage(R.mipmap.ic_launcher)
                .setPlaceholderImageScaleType(ScalingUtils.ScaleType.FIT_XY)
                .setProgressBarImage(new ProgressBarDrawable()) // 顯示進度條(Fresco自帶的進度條)
                .build();
        // 設定圖檔圓角
        RoundingParams roundingParams = new RoundingParams();
        roundingParams.setRoundAsCircle(false); // 不将圖檔剪切成圓形
        roundingParams.setCornersRadius(200);
        hierarchy.setRoundingParams(roundingParams);
        // 為SimpleDraweeView設定屬性
        sdv.setHierarchy(hierarchy);           

注意:不能把同一個GenericDraweeHierarchy對象設定給多個SimpleDraweeView!

3.3、設定下載下傳事件

sdv.setController(Fresco.newDraweeControllerBuilder()
                .setControllerListener(new BaseControllerListener<ImageInfo>() {
                    @Override
                    public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
                        // 所有圖檔都加載成功時觸發的方法
                        int width = imageInfo.getWidth();
                        int height = imageInfo.getHeight();
                        QualityInfo qualityInfo = imageInfo.getQualityInfo();
                        int quality = qualityInfo.getQuality();
                        boolean isOfFullQuality = qualityInfo.isOfFullQuality();
                        boolean isOfGoodEnoughQuality = qualityInfo.isOfGoodEnoughQuality();
                    }

                    @Override
                    public void onIntermediateImageSet(String id, ImageInfo imageInfo) {
                        // 加載漸進式圖檔時回調的方法
                    }

                    @Override
                    public void onFailure(String id, Throwable throwable) {
                        // 加載圖檔失敗時回調的方法
                    }
                })
                .setUri("http://image5.tuku.cn/pic/wallpaper/fengjing/menghuandaziranmeijingbizhi/009.jpg")
                .build());           

3.4、漸進式圖檔

漸進式圖檔是一種支援圖檔從模糊到清晰的加載模式。代碼如下:

sdv.setController(Fresco.newDraweeControllerBuilder()
                        .setImageRequest(
                                ImageRequestBuilder.newBuilderWithSource(
                                        Uri.parse("http://image5.tuku.cn/pic/wallpaper/fengjing/menghuandaziranmeijingbizhi/009.jpg"))
                                        .setProgressiveRenderingEnabled(true)
                                        .build())
                        .setOldController(sdv.getController())
                        .build());           

以上就是對Fresco的基本使用方法的介紹,希望對大家有幫助~~~

參考:

https://www.cnblogs.com/ldq2016/p/6669009.html https://www.jianshu.com/p/ef3158f76045

繼續閱讀