<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                #### 概述 Glide是一個Android的圖片加載和緩存庫,它主要專注于大量圖片的流暢加載,Glide幾乎可以勝任任何你需要使用到圖片從網絡拉取,壓縮,顯示的場景。 本文主要基于Glide4.0版本介紹其基本使用方法。 ## 1 集成 Github地址:?[https://github.com/bumptech/glide](https://github.com/bumptech/glide) app或lib級別的`build.gradle`文件添加依賴: ~~~ dependencies { compile 'com.github.bumptech.glide:glide:4.0.0-RC1' annotationProcessor 'com.github.bumptech.glide:compiler:4.0.0-RC1' } ~~~ 在`proguard.pro`/`proguard.cfg`中添加混淆: ~~~ -keep public class * implements com.bumptech.glide.module.GlideModule -keep public class * extends com.bumptech.glide.AppGlideModule -keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** { **[] $VALUES; public *; } # for DexGuard only -keepresourcexmlelements manifest/application/meta-data@value=GlideModule ~~~ ## 2 基本用法 大多數情況下**加載圖片**只需要一行代碼: ~~~ Glide.with(fragment) .load(myUrl) .into(imageView); ~~~ **取消加載**也很簡單: ~~~ Glide.with(fragment).clear(imageView); ~~~ 實際上你并不需要取消加載。。。 因為當你在`with`方法中傳入的`Activity`或`Fragment`被銷毀的時候,Glide會自動取消加載并且回收所有的加載過程中所使用的資源。 ## 3 注解(V4新特性)和自定義方法 Glide使用了`annotation processor`來生成API,允許應用修改`RequestBuilder`、`RequestOptions`和任意的包含在單一流式API庫中的方法。這是V4的特性,運用注解后使用起來更方便: ~~~ GlideApp.with(fragment) .load(myUrl) .placeholder(R.drawable.placeholder) .fitCenter() .into(imageView); ~~~ Glidev4中的`Glide.with().load()`后沒有之前版本的`fitCenter`和`placeholder`這樣的方法,但是`GlideApp`有,可以直接在builder中使用。`GlideApp`可以代替之前版本的`Glide`開頭。 這樣做的目的是: > 1.對于library項目來講可以使用自定義方法繼承Glide的API? > 2.對于應用來講,在繼承Glide的API后,可以通過添加自定義方法。 雖然你也可以手動繼承`RequestOptions`,但是顯然這樣做更加麻煩,也破壞了流式API特性。 ### 3.1 在項目中實現`AppGlideModule`: ~~~ @GlideModule public class CustomGlideModule extends AppGlideModule {} ~~~ 這個類實現必須要有`@GlideModule`注解,如果你添加的方法失效,那就檢查下這里。 如果是library就實現`LibraryGlideModule`,以使用OkHttp為例: ~~~ @GlideModule public final class OkHttpLibraryGlideModule extends LibraryGlideModule { @Override public void registerComponents(Context context, Registry registry) { registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory()); } } ~~~ [OkHttpUrlLoader](https://github.com/bumptech/glide/blob/master/integration/okhttp3/src/main/java/com/bumptech/glide/integration/okhttp3/OkHttpUrlLoader.java)是Glide的OKHttp擴展庫中的類,如果需要使用Glide的實現,可以在依賴中添加: ~~~ compile 'com.github.bumptech.glide:okhttp3-integration:4.0.0-RC1' ~~~ 添加完依賴不需要自己實現OkHttpLibraryGlideModule類,庫中已經自帶了,會自動使用OKHttp的。 然后編譯工程可以發現在build中生成了四個類: ![](http://img.blog.csdn.net/20170706120245250?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzAwNTc5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) ### 3.2 GlideExtension 為了添加新的方法,修改已有的方法或者添加對其他類型格式的支持,你需要在擴展中使用加了注解的靜態方法。 `GlideOption`用來添加自定義的方法,`GlideType`用來支持新的格式。 #### 3.2.1 GlideOption 先新建一個`CustomGlideExtension`類: ~~~ @GlideExtension public class CustomGlideExtension { //縮略圖的最小尺寸,單位:px private static final int MINI_THUMB_SIZE = 100; /** * 將構造方法設為私有,作為工具類使用 */ private CustomGlideExtension() { } /** * 1.自己新增的方法的第一個參數必須是RequestOptions options * 2.方法必須是靜態的 * @param options */ @GlideOption public static void miniThumb(RequestOptions options) { options .fitCenter() .override(MINI_THUMB_SIZE); } } ~~~ 編譯工程,打開build目錄中的`GlideOptions`,可以看見自動生成了兩個方法: ~~~ public class GlideOptions extends RequestOptions { /** * @see CustomGlideExtension#miniThumb(RequestOptions) */ public GlideOptions miniThumb() { CustomGlideExtension.miniThumb(this); return this; } /** * @see CustomGlideExtension#miniThumb(RequestOptions) */ public static GlideOptions miniThumbOf() { return new GlideOptions().miniThumb(); } ... } ~~~ 現在可以使用你自定義的方法了: ~~~ GlideApp.with(fragment) .load(url) .miniThumb(thumbnailSize) .into(imageView); ~~~ #### 3.2.2 GlideType 以添加對`GIF`格式的支持為例,只是舉例,實際上API中已經支持了。 在剛才的`CustomGlideExtension`類中加上: ~~~ @GlideExtension public class CustomGlideExtension { private static final RequestOptions DECODE_TYPE_GIF = GlideOptions.decodeTypeOf(GifDrawable.class).lock(); @GlideType(GifDrawable.class) public static void asGIF(RequestBuilder<GifDrawable> requestBuilder) { requestBuilder .transition(new DrawableTransitionOptions()) .apply(DECODE_TYPE_GIF); } } ~~~ 編譯工程,打開build目錄中的`GlideRequests`,可以看見自動生成了一個方法: ~~~ public class GlideRequests extends RequestManager { /** * @see CustomGlideExtension#asGIF(RequestBuilder) */ public GlideRequest<GifDrawable> asGIF() { GlideRequest<GifDrawable> requestBuilder = this.as(GifDrawable.class); CustomGlideExtension.asGIF(requestBuilder); return requestBuilder; } } ~~~ 現在可以使用你添加的類型了: ~~~ GlideApp.with(fragment) .asGIF() .load(url) .into(imageView); ~~~ ## 4 占位符 占位符就是請求的圖片沒加載出來時顯示的默認圖片。? Glide支持三種不同情況下的占位符: * Placeholder 請求圖片加載中 * Error 請求圖片加載錯誤 * Fallback 請求url/model為空 ### 設置占位符: ~~~ GlideApp.with(fragment) .load(url) .placeholder(R.drawable.placeholder) .error(new ColorDrawable(Color.RED)) .fallback(new ColorDrawable(Color.GREY)) .into(view); ~~~ 之后的顯示優先級,我畫了個流程圖。 ![](http://img.blog.csdn.net/20170706120204646?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzAwNTc5MQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) ## 5 Options ### 5.1 RequestOptions Glide中的大多請求參數都可以通過`RequestOptions`類和`apply()`方法來設置。 Glide中的請求參數主要有: * Placeholders 占位符 * Transformations 變換 * Caching Strategies 緩存策略 * 組件特定參數:編碼質量,解碼參數等。 比如,要將圖片的顯示方式設為`CenterCrop`,你可以這么做: ~~~ import static com.bumptech.glide.request.RequestOptions.centerCropTransform; Glide.with(fragment) .load(url) .apply(centerCropTransform(context)) .into(imageView); ~~~ 但是其實完全可以在layout文件中設置ImageView為`android:scaleType="centerCrop"`,Glide會自動根據這個屬性設置圖片的顯示方式。 `apply`方法可以調用多次,但是如果兩次`apply`存在沖突的設置,會以最后一次為準。 ### 5.2 TransitionOptions [`TransitionOptions`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/TransitionOptions.html)決定圖片加載完成如何從占位符圖片(或者之前的圖片)過渡。 * 淡入 * 交叉淡入 * 不過渡 ~~~ Glide.with(fragment) .load(url) .transition(DrawableTransitionOptions.withCrossFade()) .into(view); ~~~ **注意** > [`TransitionOptions`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/TransitionOptions.html)是和你要加載的資源的類型綁定的,也就是說,如果你請求一張位圖(Bitmap),你就需要使用[`BitmapTransitionOptions`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/load/resource/bitmap/BitmapTransitionOptions.html),而不是[`DrawableTransitionOptions`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/load/resource/drawable/DrawableTransitionOptions.html)。因此,你請求的這張位圖,你需要用簡單的淡入,而不能用? > 交叉淡入([`DrawableTransitionOptions.withCrossFade()`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/load/resource/drawable/DrawableTransitionOptions.html#withCrossFade--))。? > 如果既不是Bitmap也不是Drawable可以使用[GenericTransitionOptions](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/GenericTransitionOptions.html) ### 5.3 RequestBuilder **作用:** > 1. 指定加載類型。`asBitmap()`、`asGif()`、`asDrawable()`、`asFile()`。 > 2. 指定要加載url/model。 > 3. 指定要加載到那個View。 > 4. 指定要應用的`RequestOption` > 5. 指定要應用的`TransitionOption` > 6. 指定要加載的縮略圖 那么如何得到`RequestBuilder`呢? ~~~ RequestBuilder<Drawable> requestBuilder = Glide.with(fragment); ~~~ 默認得到一個`Drawable RequestBuilder`,如果要指定類型為Bitmap,可以這樣寫: ~~~ RequestBuilder<Bitmap> requestBuilder = Glide.with(fragment).asBitmap(); ~~~ **應用`RequestOptions`** ~~~ RequestBuilder<Drawable> requestBuilder = Glide.with(fragment); requestBuilder.apply(requestOptions); requestBuilder.transition(transitionOptions); ~~~ `RequestBuilder`也可以重復使用: ~~~ RequestBuilder<Drawable> requestBuilder = Glide.with(fragment) .asDrawable() .apply(requestOptions); for (int i = 0; i < numViews; i++) { ImageView view = viewGroup.getChildAt(i); String url = urls.get(i); requestBuilder.load(url).into(view); } ~~~ ## 6 Transformations Glide會自動讀取ImageView的縮放類型,所以一般在layout文件指定`scaleType`即可。 CenterCrop, CenterInside, CircleCrop, FitCenter, RoundedCorners Glide支持在java代碼中設置這些縮放類型: > 1. CenterCrop 縮放寬和高都到達View的邊界,有一個參數在邊界上,另一個參數可能在邊界上,也可能超過邊界 > 2. CenterInside 如果寬和高都在View的邊界內,那就不縮放,否則縮放寬和高都進入View的邊界,有一個參數在邊界上,另一個參數可能在邊界上,也可能在邊界內 > 3. CircleCrop 圓形且結合了CenterCrop的特性 > 4. FitCenter 縮放寬和高都進入View的邊界,有一個參數在邊界上,另一個參數可能在邊界上,也可能在邊界內 > 5. RoundedCorners 圓角 有三種用法: ### 1 使用RequestOptions ~~~ RequestOptions options = new RequestOptions(); options.centerCrop(); Glide.with(fragment) .load(url) .apply(options) .into(imageView); ~~~ ### 2 使用RequestOptions中的transform方法 ~~~ Glide.with(fragment) .load(url) .apply(RequestOptions.fitCenterTransform()) .into(imageView); ~~~ ### 3 V4特性 ~~~ GlideApp.with(fragment) .load(url) .fitCenter() .into(imageView); ~~~ 第三種方法最簡便,推薦。 ### 多個變換 ~~~ Glide.with(fragment) .load(url) .transform(new MultiTransformation(new FitCenter(), new YourCustomTransformation()) .into(imageView); ~~~ ## 7 Transitions(動畫) ### 普通動畫 Glide中的過渡動畫是指占位符到請求圖片或縮略圖到完整尺寸請求圖片的動畫。過渡動畫只能針對單一請求,不能跨請求執行。 過渡動畫執行時機: > 1.圖片在磁盤緩存? > 2.圖片在本地? > 3.圖片在遠程 如果圖片在內存緩存上是不會執行過渡動畫的。如果需要在內存緩存上加載動畫,可以這樣: ~~~ GlideApp.with(this).load(R.drawable.img_default).listener(new RequestListener(){ @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { return false; } @Override public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { if (dataSource == DataSource.MEMORY_CACHE) { //當圖片位于內存緩存時,glide默認不會加載動畫 imageView.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in)); } return false; } }).fitCenter().transition(GenericTransitionOptions.with(R.anim.fade_in)).into(imageView); ~~~ 通常的用法如下: ~~~ Glide.with(fragment) .load(url) .transition(DrawableTransitionOptions.withCrossFade()) .into(view); ~~~ `TransitionOptions`的介紹:[TransitionOptions](http://blog.csdn.net/u013005791/article/details/74532091#TransitionOptions)。有三種TransitionOptions: 1. `GenericTransitionOptions`?通用型 2. `DrawableTransitionOptions` 3. `BitmapTransitionOptions` 如果要使用自定義的動畫,可以使用`GenericTransitionOptions.with(int viewAnimationId)`或者`BitmapTransitionOptions.withCrossFade(int animationId, int duration)`或者`DrawableTransitionOptions.withCrossFade(int animationId, int duration)`。 出于性能考慮,最好不要在ListView,GridView,RecycleView中使用過渡動畫,使用`TransitionOptions.dontTransition()`可以不加載動畫,也可以使用`dontAnimate`不加載動畫 ~~~ GlideApp.with(mContext) .load(imgUrl) .placeholder(R.drawable.img_default) .dontAnimate() .into(holder.imageview); ~~~ ### 自定義過渡動畫 **1.實現[`TransitionFactory`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/request/transition/TransitionFactory.html)**? **2.重寫[`build()`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/request/transition/TransitionFactory.html#build-com.bumptech.glide.load.DataSource-boolean-)**? 可以控制圖片在內存緩存上是否執行動畫。 具體寫法參考[DrawableCrossFadeFactory](https://github.com/bumptech/glide/blob/8f22bd9b82349bf748e335b4a31e70c9383fb15a/library/src/main/java/com/bumptech/glide/request/transition/DrawableCrossFadeFactory.java#L35),然后調用`TransitionOptions`的`with(TransitionFactory transitionFactory)`加載。 ## 8 基本配置 ### 8.1 配置內存緩存 Glide會自動合理分配內存緩存,但是也可以自己手動分配。 #### 方法一 通過MemorySizeCalculator設置 ~~~ @GlideModule public class CustomGlideModule extends AppGlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { MemorySizeCalculator calculator = new MemorySizeCalculator.Builder(context) .setMemoryCacheScreens(2) .build(); builder.setMemoryCache(new LruResourceCache(calculator.getMemoryCacheSize())); } } ~~~ [`setMemoryCacheScreens`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/load/engine/cache/MemorySizeCalculator.Builder.html#setMemoryCacheScreens-float-)設置MemoryCache應該能夠容納的像素值的設備屏幕數,說白了就是緩存多少屏圖片,默認值是2。 #### 方法二 ~~~ @GlideModule public class CustomGlideModule extends AppGlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { int memoryCacheSizeBytes = 1024 * 1024 * 20; // 20mb builder.setMemoryCache(new LruResourceCache(memoryCacheSizeBytes)); } } ~~~ #### 方法三 ~~~ @GlideModule public class YourAppGlideModule extends AppGlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { builder.setMemoryCache(new CustomGlideMemoryCache()); } } ~~~ 自己實現[`MemoryCache`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/load/engine/cache/MemoryCache.html)接口。 清楚內存緩存,在主線程調用: ~~~ GlideApp.get(context).clearMemory(); ~~~ 在使用的時候,可以跳過內存緩存: ~~~ GlideApp.with(getActivity()) .load(url) .skipMemoryCache(true) .dontAnimate() .centerCrop() .into(imageView); ~~~ ### 8.2 磁盤緩存 Glide使用[`DiskLruCacheWrapper`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/load/engine/cache/DiskLruCacheWrapper.html)作為默認的磁盤緩存,默認大小是250M,緩存文件放在APP的緩存文件夾下。 ~~~ @GlideModule public class CustomGlideModule extends AppGlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { int diskCacheSizeBytes = 1024 * 1024 * 100; // 100 MB builder.setDiskCache(new InternalCacheDiskCacheFactory(context, diskCacheSizeBytes)); // builder.setDiskCache(new InternalCacheDiskCacheFactory(context, "cacheFolderName", diskCacheSizeBytes)); // builder.setDiskCache(new ExternalCacheDiskCacheFactory(context)); } } ~~~ 用法如上,可以指定緩存在內部存儲或外部存儲,也可以指定緩存大小和文件夾。 **自定義磁盤緩存** ~~~ @GlideModule public class CustomGlideModule extends AppGlideModule { @Override public void applyOptions(Context context, GlideBuilder builder) { builder.setDiskCache(new DiskCache.Factory() { @Override public DiskCache build() { return new YourAppCustomDiskCache(); } }); } } ~~~ 自己實現[`DiskCache`](http://bumptech.github.io/glide/javadocs/400/com/bumptech/glide/load/engine/cache/DiskCache.html)接口。 清楚磁盤緩存,在主線程調用: ~~~ GlideApp.get(context).clearDiskCache(); ~~~ 加載圖片時設置磁盤緩存策略: ~~~ GlideApp.with(getActivity()) .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .dontAnimate() .centerCrop() .into(imageView); ~~~ 默認的策略是`DiskCacheStrategy.AUTOMATIC`? DiskCacheStrategy有五個常量: * DiskCacheStrategy.ALL 使用DATA和RESOURCE緩存遠程數據,僅使用RESOURCE來緩存本地數據。 * DiskCacheStrategy.NONE 不使用磁盤緩存 * DiskCacheStrategy.DATA 在資源解碼前就將原始數據寫入磁盤緩存 * DiskCacheStrategy.RESOURCE 在資源解碼后將數據寫入磁盤緩存,即經過縮放等轉換后的圖片資源。 * DiskCacheStrategy.AUTOMATIC 根據原始圖片數據和資源編碼策略來自動選擇磁盤緩存策略。 ### 8.3 禁止解析Manifest文件 主要針對V3升級到v4的用戶,可以提升初始化速度,避免一些潛在錯誤。 ~~~ @GlideModule public class CustomGlideModule extends AppGlideModule { @Override public boolean isManifestParsingEnabled() { return false; } } ~~~ ### 8.4 View尺寸 Glide對ImageView的`width`和`height`屬性是這樣解析的: > * 如果`width`和`height`都大于0,則使用layout中的尺寸。 > * 如果`width`和`height`都是`WRAP_CONTENT`,則使用屏幕尺寸。 > * 如果`width`和`height`中至少有一個值<=0并且不是`WRAP_CONTENT`,那么就會在布局的時候添加一個`OnPreDrawListener`監聽ImageView的尺寸 Glide對`WRAP_CONTENT`的支持并不好,所以盡量不要用。 那么如何在運行修改ImageView尺寸呢? #### 方法一 繼承ImageViewTarget 我這里指定的View的類型是ImageView,資源類型是Bitmap,可根據需要修改,`onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition)`方法中可以通過bitmap獲取圖片的尺寸。 ~~~ public class CustomImageViewTarget extends ImageViewTarget<Bitmap> { private int width, height; public CustomImageViewTarget(ImageView view) { super(view); } public CustomImageViewTarget(ImageView view, int width, int height) { super(view); this.width = width; this.height = height; } @Override public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) { } @Override protected void setResource(@Nullable Bitmap resource) { view.setImageBitmap(resource); } @Override public void getSize(SizeReadyCallback cb) { if (width > 0 && height > 0) { cb.onSizeReady(width, height); return; } super.getSize(cb); } } ~~~ 使用: ~~~ GlideApp.with(context) .asBitmap() .load(url) .dontAnimate() .placeholder(R.drawable.img_default) .into(new CustomImageViewTarget(imageview, 300, 300)); ~~~ #### 方法二 使用override() ~~~ GlideApp.with(mContext) .load(url) .override(width,height) .into(view); ~~~ ### 8.5 Recycle的加載優化 只在拖動和靜止時加載,自動滑動時不加載。 ~~~ recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); switch (newState) { case RecyclerView.SCROLL_STATE_DRAGGING: GlideApp.with(context).resumeRequests(); break; case RecyclerView.SCROLL_STATE_SETTLING: GlideApp.with(context).pauseRequests(); break; case RecyclerView.SCROLL_STATE_IDLE: GlideApp.with(context).resumeRequests(); break; } } }); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看