Glide使用


  • 在一個 Gradle 項(xiàng)目中在你的 build.gradle中添加下面這行代碼:
compile 'com.github.bumptech.glide:glide:+'
  • 從一個 URL 中加載圖片
    就像 Picasso, Glide 庫是使用流接口(fluent interface)。對一個完整的功能請求,Glide 建造者要求最少有三個參數(shù)。
    • with(Context context) - 對于很多 Android API 調(diào)用,Context 是必須的。Glide 在這里也一樣

    • load(String imageUrl) - 這里你可以指定哪個圖片應(yīng)該被加載,同上它會是一個字符串的形式表示一個網(wǎng)絡(luò)圖片的 URL

    • into(ImageView targetImageView)你的圖片會顯示到對應(yīng)的 ImageView 中。

ImageView targetImageView = (ImageView) findViewById(R.id.imageView);
String internetUrl = "http://i.imgur.com/DvpvklR.png";
Glide
       .with(context) 
       .load(internetUrl) 
       .into(targetImageView);
  • 從資源中加載圖片
  • 從文件中加載
    當(dāng)你讓用戶選擇一張照片去顯示圖像(比如畫廊)這可能會比較有用。該參數(shù)只是一個文件
    對象。
//這個文件可能不存在于你的設(shè)備中。然而你可以用任何文件路徑,去指定一個圖片路徑。
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Running.jpg");
Glide .with(context) .load(file) .into(imageViewFile);
  • 從 Uri 中加載圖片

Glide 的一個優(yōu)勢:緩存
Glide 的緩存實(shí)現(xiàn)是基于 Picasso,當(dāng)加載圖片時,Glide 使用3個來源:內(nèi)存,磁盤和網(wǎng)絡(luò)(從最快到最慢排序)。

占位符和漸現(xiàn)動畫
Glide 的流式接口只需要調(diào)用 .placeHolder()用一個 drawable(resource) 引用,Glide 將會顯示它作為一個占位符,直到你的實(shí)際圖片準(zhǔn)備好。

Glide 
      .with(context) 
      .load(UsageExampleListViewAdapter.eatFoodyImages[0])
      .placeholder(R.mipmap.ic_launcher) // 也可以是一個drawable 
      .into(imageViewPlaceholder);

不能設(shè)置一個網(wǎng)絡(luò) url 作為占位符,因?yàn)檫@也會被去請求加載的。App 資源和 drawable 能保證可用和可訪問的。然而,作為 load()方法的參數(shù),Glide 接受所有值。

當(dāng)App 嘗試從一個網(wǎng)站去加載一張圖片,但由于某些原因加載失敗,使用錯誤占位符:.error(),在大多數(shù)情況下使用占位符,來指明圖片不能被加載已經(jīng)足夠了。

Glide 
    .with(context) 
    .load("http://futurestud.io/non_existing_image.png") 
    .placeholder(R.mipmap.ic_launcher) // 也可以是一個drawable 
    .error(R.mipmap.future_studio_launcher) // 如果圖片不能加載就會顯示
    .into(imageViewError);

error()接受的參數(shù)只能是已經(jīng)初始化的 drawable 對象或者指明它的資源。

Glide 使用標(biāo)準(zhǔn)的淡入淡出動畫,這是默認(rèn)激活的。如果你想要如強(qiáng)制 Glide 顯示一個淡入淡出動畫,你必須調(diào)用另外一個建造者:

Glide 
    .with(context) 
    .load("http://futurestud.io/non_existing_image.png") 
    .placeholder(R.mipmap.ic_launcher) // 也可以是一個drawable 
    .error(R.mipmap.future_studio_launcher) // 如果圖片不能加載就會顯示
    .
    .into(imageViewError);

crossFade()方法還有另外重載方法 .crossFade(int duration)。如果你想要去減慢(或加快)動畫,隨時可以傳一個毫秒的時間給這個方法。動畫默認(rèn)的持續(xù)時間是 300毫秒。

用 resize(x,y) 調(diào)整圖片大小
Glide 自動限制了圖片的尺寸在緩存和內(nèi)存中,并給到 ImageView需要的尺寸。如果圖片不會自動適配到 ImageView,調(diào)用 override(horizontalSize, verticalSize) 。這將在圖片顯示到 ImageView之前重新改變圖片大小。

Glide 
    .with(context) 
    .load(UsageExampleListViewAdapter.eatFoodyImages[0])
    .override(600, 200) // 重新改變圖片大小成這些尺寸(像素).不關(guān)心長寬比
    .into(imageViewResize);

當(dāng)你還沒有目標(biāo) view 去知道尺寸的時候,這個選項(xiàng)也可能是有用的。比如,如果 App 想要在閃屏界面預(yù)熱緩存,它還不能測量 ImageView的尺寸。然而,如果你知道這個圖片多少大,用 override 去提供明確的尺寸。

縮放圖像

  • CenterCrop
    CenterCrop()是一個裁剪技術(shù),即縮放圖像讓它填充到 ImageView
    界限內(nèi)并且裁剪額外的部分。ImageView可能會完全填充,但圖像可能不會完整顯示。
Glide 
    .with(context) 
    .load(UsageExampleListViewAdapter.eatFoodyImages[0]) 
    .override(600, 200) // 重新改變圖片大小成這些尺寸(像素)比
    .centerCrop() // 這種裁剪技術(shù)縮放圖像,使其填充請求的邊界,然后裁剪額外的。
    .into(imageViewResizeCenterCrop);
  • FitCenter
    fitCenter()是裁剪技術(shù),即縮放圖像讓圖像都測量出來等于或小于 ImageView的邊界范圍。該圖像將會完全顯示,但可能不會填滿整個 ImageView。
Glide 
    .with(context) 
    .load(UsageExampleListViewAdapter.eatFoodyImages[0]) 
    .override(600, 200) 
    .fitCenter() 
    .into(imageViewResizeFitCenter);

顯示 Gif
檢查圖片加載的是否是一個gif圖片,調(diào)用一個額外的防區(qū)強(qiáng)制 Glide變成一個 Gif asGif()

String gifUrl = "http://i.kinja-img.com/gawker-media/image/upload/s--B7tUiM5l--/gf2r69yorbdesguga10i.gif";
Glide 
    .with( context ) 
    .load( gifUrl ) 
    .asGif() 
    .error( R.drawable.full_cake ) 
    .into( imageViewGif );

如果這個 gifUrl 不是一個 Gif,.error()回調(diào)被調(diào)用并且錯誤占位符被顯示。

Gif 轉(zhuǎn)為 Bitmap
如果你僅僅想要顯示 Gif 的第一幀,你可以調(diào)用 asBitmap()去保證其作為一個常規(guī)的圖片顯示,即使這個 URL 是一個 Gif。

Glide 
    .with( context ) 
    .load( gifUrl ) 
    .asBitmap() 
    .into( imageViewGifAsBitmap );

內(nèi)存緩存
Glide 通過使用默認(rèn)的內(nèi)存和磁環(huán)緩存去避免不必要的網(wǎng)絡(luò)請求。調(diào)用了 .skipMemoryCache(true)去明確告訴 Glide 跳過內(nèi)存緩存。可以用 .diskCacheStrategy()方法為 Glide 改變磁盤緩存的行為,如果要為一個請求禁用磁盤緩存。使用枚舉 DiskCacheStrategy.NONE。
作為參數(shù)。

Glide 
    .with( context ) 
    .load( eatFoodyImages[0] ) 
    .diskCacheStrategy( DiskCacheStrategy.NONE ) 
    .skipMemoryCache( true ) 
    .into( imageViewInternet );

Glide 緩存了原始圖像,全分辨率圖像和另外小版本的圖像。對于 .diskCacheStrategy()方法來說不同的枚舉參數(shù)的意義:

  • DiskCacheStrategy.NONE什么都不緩存
  • DiskCacheStrategy.SOURCE僅僅只緩存原來的全分辨率的圖像。
  • DiskCacheStrategy.RESULT僅僅緩存最終的圖像,即降低分辨率后的(或者是轉(zhuǎn)換后的)(默認(rèn)行為
  • DiskCacheStrategy.ALL緩存所有版本的圖像

如果有一張圖片,將會經(jīng)常操作處理,并做了一堆不同的版本,對其有意義的僅僅是緩存原始分辨率圖片,用 DiskCacheStrategy.SOURCE。

圖片請求的優(yōu)先級
Priority (優(yōu)先級)枚舉

  • Priority.LOW
  • Priority.NORMAL
  • Priority.HIGH
  • Priority.IMMEDIATE

你正在實(shí)現(xiàn)一個信息詳情頁面,有一個英雄圖片在頂部,和較小的圖片在底部。對于最好的用戶體驗(yàn)來說,英雄圖片首先需要被加載。因此,我們用 Priority.HIGH
來處理它。理論上說,這應(yīng)該夠了,但是為了讓這個實(shí)例增加點(diǎn)趣味,我們也將底層圖像分配給低優(yōu)先級,用 .priority(Priority.LOW)
調(diào)用:

private void loadImageWithHighPriority() {
  Glide 
    .with( context ) 
    .load( UsageExampleListViewAdapter.eatFoodyImages[0] ) 
    .priority( Priority.HIGH ) 
    .into( imageViewHero );
}
private void loadImagesWithLowPriority() { 
  Glide
    .with( context ) 
    .load( UsageExampleListViewAdapter.eatFoodyImages[1] ) 
    .priority( Priority.LOW ) 
    .into( imageViewLowPrioLeft ); 
  Glide 
    .with( context ) 
    .load( UsageExampleListViewAdapter.eatFoodyImages[2] ) 
    .priority( Priority.LOW ) 
    .into( imageViewLowPrioRight );
}

縮略圖
用原圖的1/10作為縮略圖

Glide 
.with(this) 
.load(UsageExampleGifAndVideos.gifUrl) 
.thumbnail(0.1f) 
.into(imageView2); 

用其它圖片作為縮略圖


DrawableRequestBuilder<String> thumbnailRequest = 
    Glide 
      .with(this) 
      .load(R.drawable.news); 
Glide
    .with(this) 
    .load(UsageExampleGifAndVideos.gifUrl)
    .thumbnail(thumbnailRequest) 
    .into(imageView3);

Glide 中的回調(diào):Targets
Glide 提供了一個用 Targets的簡單的方式去接受圖片資源的 Bitmap。Targets 是沒有任何別的回調(diào),它在 Glide 做完所有的加載和處理之后返回結(jié)果。

  • SimpleTarget:
private SimpleTarget target2 = new SimpleTarget<Bitmap>(250, 250) { 
    @Override 
    public void onResourceReady(Bitmap bitmap, GlideAnimation glideAnimation) 
    { 
        imageView2.setImageBitmap(bitmap); 
    }
};
private void loadImageSimpleTargetApplicationContext() { 
    Glide 
        .with( context.getApplicationContext() ) // 如果你target 是獨(dú)立于應(yīng)用的 activity 生命周期,如果請求需要在 activity 生命周期之外去做時,才用這樣的代碼
        .load(eatFoodyImages[1]) 
        .asBitmap() 
        .into(target2);
}
  • ViewTarget:
    Glide 可以用 ViewTarget加載圖片到自定義 view 中。
    首先自定義 View,它繼承自 FrameLayout并內(nèi)部使用了一個 ImageView以及覆蓋了一個 TextView。
public class TargetView extends FrameLayout { 
    ImageView iv; 
    TextView tv; 
    public void initialize(Context context) { 
        inflate(context, R.layout.custom_view_target, this); 
        iv = (ImageView) findViewById(R.id.custom_view_image);
        tv = (TextView) findViewById(R.id.custom_view_text);
    } 
    public TargetView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        initialize(context); 
    } 
    public TargetView(Context context, AttributeSet attrs, int defStyleAttr) { 
        super(context, attrs, defStyleAttr); 
        initialize( context ); 
    } 
    public void setImage(Drawable drawable) { 
        iv = (ImageView) findViewById( R.id.custom_view_image );         
        iv.setImageDrawable(drawable); 
    }
}

不能使用常規(guī)的 Glide 的方法 .into(),因?yàn)槲覀兊淖远x view 并不繼承自 ImageView。因此,我們必須創(chuàng)建一個 ViewTarget,并用 .into()方法:

private void loadImageViewTarget() { 
    TargetView customView = (TargetView) findViewById( R.id.custom_view ); 
    ViewTarget viewTarget = new ViewTarget<TargetView, GlideDrawable>( customView ) { 
        @Override 
        public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) { 
              this.view.setImage( resource.getCurrent() ); 
        }
     }; 
    Glide 
        .with( context.getApplicationContext() ) // safer! 
        .load( eatFoodyImages[2] ) 
        .into( viewTarget );
}
  • 加載圖片到 Notifications(重點(diǎn))----NotificationTarget
    首先編寫通知欄
<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"     
    android:background="@android:color/white" 
    android:orientation="vertical"> 

    <LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:padding="2dp">
       <ImageView 
            android:id="@+id/remoteview_notification_icon"     
            android:layout_width="50dp" 
            android:layout_height="50dp"         
            android:layout_marginRight="2dp" 
            android:layout_weight="0" 
            android:scaleType="centerCrop"/> //按比例擴(kuò)大圖片的size居中顯示,使得圖片長(寬)等于或大于View的長(寬)
      <LinearLayout 
            android:layout_width="0dp" 
            android:layout_height="wrap_content" 
            android:layout_weight="1" 
            android:orientation="vertical"> 
            <TextView 
                android:id="@+id/remoteview_notification_headline" 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:ellipsize="end"  //內(nèi)容過長加省略號的屬性,省略號在結(jié)尾
                android:singleLine="true"
                android:textSize="12sp"/> 
          <TextView                 
                android:id="@+id/remoteview_notification_short_message"                 
                android:layout_width="match_parent" 
                android:layout_height="wrap_content" 
                android:ellipsize="end" 
                android:paddingBottom="2dp" 
                android:singleLine="true" 
                android:textSize="14sp"
                android:textStyle="bold"/> 
         </LinearLayout> 
    </LinearLayout>
</LinearLayout> 

創(chuàng)建一個自定義通知

final RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.remoteview_notification);
rv.setImageViewResource(R.id.remoteview_notification_icon, R.mipmap.future_studio_launcher);
rv.setTextViewText(R.id.remoteview_notification_headline, "Headline"); 
rv.setTextViewText(R.id.remoteview_notification_short_message, "Short Message");// build notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) 
    .setSmallIcon(R.mipmap.future_studio_launcher) 
    .setContentTitle("Content Title") 
    .setContentText("Content Text") 
    .setContent(rv) 
    .setPriority( NotificationCompat.PRIORITY_MIN);
final Notification notification = mBuilder.build();
// set big content view for newer androids
if (android.os.Build.VERSION.SDK_INT >= 16) { 
notification.bigContentView = rv;
}
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
mNotificationManager.notify(NOTIFICATION_ID, notification); 

上述創(chuàng)建了三個重要的對象,notification和 RemoteViews以及常量 NOTIFICATION_ID。利用這些去創(chuàng)建一個通知 target。

private NotificationTarget notificationTarget;
...
notificationTarget = new NotificationTarget( 
    context, 
    rv, 
    R.id.remoteview_notification_icon, 
    notification, 
    NOTIFICATION_ID);

調(diào)用 Glide,將 target 作為 .into()的參數(shù)。

Glide 
    .with( context.getApplicationContext() )
    .load( eatFoodyImages[3] ) 
    .asBitmap() 
    .into( notificationTarget );

Transformations(轉(zhuǎn)換)
在圖片被顯示之前,transformations(轉(zhuǎn)換) 可以被用于圖像的操作處理。圖片的任意屬性:顏色、尺寸、范圍、顏色、像素位置等等。下面的庫它為 Glide 轉(zhuǎn)換提供了多種多樣的實(shí)現(xiàn):
glide-transformations

用 animate() 自定義動畫
創(chuàng)建自己的 XML 動畫,比如一個小的縮放動畫,圖片剛開始小的,然后逐漸增大到原尺寸。

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
android:fillAfter="true">
<scale
    android:duration="@android:integer/config_longAnimTime"     
    android:fromXScale="0.1" 
    android:fromYScale="0.1" 
    android:pivotX="50%"  
    android:pivotY="50%" //這兩個屬性控制著View對象的支點(diǎn)位置,圍繞這個支點(diǎn)進(jìn)行旋轉(zhuǎn)和縮放變換處理
    android:toXScale="1"  //縮放
    android:toYScale="1"/>
</set> 

這兩個動畫可以添加到Glid中

Glide 
    .with( context ) 
    .load( eatFoodyImages[0] ) 
    .animate( android.R.anim.slide_in_left ) //或者R.anim.zoom_in 
    .into( imageView1 );

  • 集成網(wǎng)絡(luò)棧
    集成 OkHttp 作為你給 Glide 的網(wǎng)絡(luò)庫,在build.gradle依賴中添加下面這兩行代碼:
dependencies { 
    // your other dependencies 
    // ...
    //Glide 
    compile 'com.github.bumptech.glide:glide:3.6.1' 
    // Glide's OkHttp Integration 
    compile 'com.github.bumptech.glide:okhttp-integration:1.3.1@aar' 
    compile 'com.squareup.okhttp:okhttp:2.5.0'
}

  • 用 Module 自定義 Glide
    為了定制 Glide,你需要去實(shí)現(xiàn)一個GlideModule接口的公共類。
public class SimpleGlideModule implements GlideModule { 
    @Override 
    public void applyOptions(Context context, GlideBuilder builder) { 
        // todo 
    } 
    @Override 
    public void registerComponents(Context context, Glide glide) { 
        // todo 
    }
}

在 AndroidManifest.xml的 <application>標(biāo)簽內(nèi)去聲明這個剛剛創(chuàng)建的 Glide module。

<manifest 
    ... 
    <application> 
          <meta-data     
               android:name="io.futurestud.tutorials.glide.glidemodule.SimpleGlideModule" 
               android:value="GlideModule" />
     ... 
    </application>
</manifest> 

android:name屬性是包名+類名的形式。
要看第一個方法applyOptions(Context context, GlideBuilder builder),可以在這個方法里去調(diào) GlideBuilder中可用的方法。

  • setMemoryCache(MemoryCache memoryCache)
  • setBitmapPool(BitmapPool bitmapPool)
  • setDiskCache(DiskCache.Factory diskCacheFactory)
  • setDiskCacheService(ExecutorService service)
  • setResizeService(ExecutorService service)
  • setDecodeFormat(DecodeFormat decodeFormat)
    可以通過這些方法改變磁盤緩存,內(nèi)存緩存等等。
    示例:增加 Glide 的圖片質(zhì)量
    在 Android 中有兩個主要的方法對圖片進(jìn)行解碼:ARGB8888 和 RGB565。前者為每個像素使用了 4 個字節(jié),后者僅為每個像素使用了 2 個字節(jié)。ARGB8888 的優(yōu)勢是圖像質(zhì)量更高以及能存儲一個 alpha 通道。Glide 默認(rèn)使用低質(zhì)量的 RGB565。可以使用 Glide module 方法去改變解碼規(guī)則。
public class SimpleGlideModule implements GlideModule { 
    @Override 
    public void applyOptions(Context context, GlideBuilder builder) { 
        builder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888); 
    } 
    @Override 
    public void registerComponents(Context context, Glide glide) { 
        // nothing to do here 
    }
}

  • 接受自簽名證書的 HTTPS
    可能是當(dāng)你的圖片從服務(wù)端獲取時,是使用HTTPS,且是自簽名的(self-signed)。這時 Glide 不會下載或顯示圖片了,因?yàn)樽院灻淖C書被認(rèn)為是一個安全的問題。

參考:
Glide系列教程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容