- 在一個 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系列教程