您现在的位置是:首页 > 文章详情

Android Studio 第五十四期 - 超级巨图Glide3.7和Glide4.1.1优化加载方案

日期:2017-09-19点击:660

wKiom1nAst7gJXLWAApAOtlw0r4105.jpg  wKioL1nA-WrQ8NSkAADpAlDnsrM054.jpg


wKiom1nA9iSRwF1BADe7ZVL2w4Q127.jpg

    相信大家看到上面的巨图会很懵逼~最近产品经理朝令夕改,有点烦,要不是还有外包项目在做,就不想干了,所以忍了,先做完十一后再说,毕竟找工作还是有点折腾,需要更高的薪水和技术的沉淀。好吧,啰嗦了一把,下面开始正题,最近一直在研究glide3.7和glide4.1.1,两者的方法确实改变不少,网上给的方案大多都是浅显的使用,目前没有找到git上详细使用的开源的统一的代码,我也是查了一周的代码,最后还是搞出来了一些东西,希望可以帮到你。

    首先是glide3.7的使用,比较单一,如果你要结合okhttp一起使用,全部的代码引用如下代码:

//glide37 compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar' compile 'com.squareup.okhttp3:okhttp:3.4.2'

    使用的话如下代码:

GlideUtil.display(context, viewHolder.iv_imgurl, ratings.getSku_p_w_picpath(), GlideOptionsFactory.get(GlideOptionsFactory.Type.RADIUS)); Glide.with(context).load(ratings.getSku_p_w_picpath()).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE).into(viewHolder.iv_imgurl); GlideOptions glideOptions = new GlideOptions(R.drawable.ic_def_loading, R.drawable.ic_def_loading, 300); GlideUtil.display(context, viewHolder.iv1, ratings.getImg_url(), glideOptions);

    这里说一下,我封装了一下3.7的方法,可以自定义圆角,但是清理缓存的操作建议还是用原生的方法。

    可以参考之前写的demo:

    https://github.com/geeklx/MyApplication/tree/master/P009_Glide图片缓存

    3.7还是很好用的,目前项目中大家应该都在用这个版本,不过4.0出来以后大幅度修改了API让很多人望而却步,我也是因为怕被技术无形的淘汰,逼了自己一把,把4.1.1的版本API都看了一遍,整体感觉4.1.1的版本还是要好一些,如果说3.7只是基础的用法,那么4.1.1就是晋升之路,学会后你会发现,有很多市面上你见过的通用的业务都不需要你去自己写页面,glide4.1.1会给你提供很好的自定义解决方案。

    下面开始正题:当你遇到清明上河图或者微博的大图预览,你会怎么做?是不是按部就班的画页面,传值,折腾几夜,然后也做出来了,挺辛苦和费劲的。现在glide4.1.1就提供了很好的便利,再说4.1.1之前先看看3.7怎么封装它,让它也实现功能。

    Glide3.7基础用法以及大图预览放大效果:

    LargeImageViewTarget:

package com.example.shining.p042_largep_w_picpath.glide37; import android.graphics.drawable.Drawable; import android.view.View; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.ViewTarget; import com.shizhefei.view.largep_w_picpath.ILargeImageView; import com.shizhefei.view.largep_w_picpath.factory.FileBitmapDecoderFactory; import java.io.File; /**  * A base {@link com.bumptech.glide.request.target.Target} for displaying resources in  * {@link android.widget.ImageView}s.  *  * @param <Z> The type of resource that this target will display in the wrapped {@link android.widget.ImageView}.  */ public class LargeImageViewTarget extends ViewTarget<View, File>{     private ILargeImageView largeImageView;     public <V extends View & ILargeImageView> LargeImageViewTarget(V view) {         super(view);         this.largeImageView = view;     }     /**      * Sets the given {@link android.graphics.drawable.Drawable} on the view using      * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.      *      * @param placeholder {@inheritDoc}      */     @Override     public void onLoadStarted(Drawable placeholder) {         largeImageView.setImageDrawable(placeholder);     }     /**      * Sets the given {@link android.graphics.drawable.Drawable} on the view using      * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.      *      * @param errorDrawable {@inheritDoc}      */     @Override     public void onLoadFailed(Exception e, Drawable errorDrawable) {         largeImageView.setImageDrawable(errorDrawable);     }     @Override     public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {         largeImageView.setImage(new FileBitmapDecoderFactory(resource));     }     /**      * Sets the given {@link android.graphics.drawable.Drawable} on the view using      * {@link android.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}.      *      * @param placeholder {@inheritDoc}      */     @Override     public void onLoadCleared(Drawable placeholder) {         largeImageView.setImageDrawable(placeholder);     } }

    OkHttpProgressGlideModule:

package com.example.shining.p042_largep_w_picpath.glide37; import android.content.Context; import android.os.Handler; import android.os.Looper; import com.bumptech.glide.Glide; import com.bumptech.glide.GlideBuilder; import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.module.GlideModule; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import okio.Buffer; import okio.BufferedSource; import okio.ForwardingSource; import okio.Okio; import okio.Source; // TODO add <meta-data android:value="GlideModule" android:name="....OkHttpProgressGlideModule" /> // TODO add <meta-data android:value="GlideModule" tools:node="remove" android:name="com.bumptech.glide.integration.okhttp.OkHttpGlideModule" /> // or not use 'okhttp@aar' in Gradle depdendencies public class OkHttpProgressGlideModule implements GlideModule {     @Override     public void applyOptions(Context context, GlideBuilder builder) {     }     @Override     public void registerComponents(Context context, Glide glide) {         OkHttpClient.Builder builder = new OkHttpClient.Builder();         builder.networkInterceptors().add(createInterceptor(new DispatchingProgressListener()));         glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(builder.build()));     }     private static Interceptor createInterceptor(final ResponseProgressListener listener) {         return new Interceptor() {             @Override             public Response intercept(Chain chain) throws IOException {                 Request request = chain.request();                 Response response = chain.proceed(request);                 return response.newBuilder()                         .body(new OkHttpProgre***esponseBody(request.url(), response.body(), listener))                         .build();             }         };     }     public interface UIProgressListener {         void onProgress(long bytesRead, long expectedLength);         /**          * Control how often the listener needs an update. 0% and 100% will always be dispatched.          *          * @return in percentage (0.2 = call {@link #onProgress} around every 0.2 percent of progress)          */         float getGranualityPercentage();     }     public static void forget(String url) {         DispatchingProgressListener.forget(url);     }     public static void expect(String url, UIProgressListener listener) {         DispatchingProgressListener.expect(url, listener);     }     private interface ResponseProgressListener {         void update(HttpUrl url, long bytesRead, long contentLength);     }     private static class DispatchingProgressListener implements ResponseProgressListener {         private static final Map<String, UIProgressListener> LISTENERS = new ConcurrentHashMap<>();         private static final Map<String, Long> PROGRESSES = new ConcurrentHashMap<>();         private final Handler handler;         DispatchingProgressListener() {             this.handler = new Handler(Looper.getMainLooper());         }         static void forget(String url) {             LISTENERS.remove(url);             PROGRESSES.remove(url);         }         static void expect(String url, UIProgressListener listener) {             LISTENERS.put(url, listener);         }         @Override         public void update(HttpUrl url, final long bytesRead, final long contentLength) {             //System.out.printf("%s: %d/%d = %.2f%%%n", url, bytesRead, contentLength, (100f * bytesRead) / contentLength);             String key = url.toString();             final UIProgressListener listener = LISTENERS.get(key);             if (listener == null) {                 return;             }             //长度是错误的移除监听             if (contentLength <= bytesRead) {                 forget(key);             }             if (needsDispatch(key, bytesRead, contentLength, listener.getGranualityPercentage())) {                 handler.post(new Runnable() {                     @Override                     public void run() {                         listener.onProgress(bytesRead, contentLength);                     }                 });             }         }         private boolean needsDispatch(String key, long current, long total, float granularity) {             if (granularity == 0 || current == 0 || total == current) {                 return true;             }             float percent = 100f * current / total;             long currentProgress = (long) (percent / granularity);             Long lastProgress = PROGRESSES.get(key);             if (lastProgress == null || currentProgress != lastProgress) {                 PROGRESSES.put(key, currentProgress);                 return true;             } else {                 return false;             }         }     }     private static class OkHttpProgre***esponseBody extends ResponseBody {         private final HttpUrl url;         private final ResponseBody responseBody;         private final ResponseProgressListener progressListener;         private BufferedSource bufferedSource;         OkHttpProgre***esponseBody(HttpUrl url, ResponseBody responseBody,                                    ResponseProgressListener progressListener) {             this.url = url;             this.responseBody = responseBody;             this.progressListener = progressListener;         }         @Override         public MediaType contentType() {             return responseBody.contentType();         }         @Override         public long contentLength() {             return responseBody.contentLength();         }         @Override         public BufferedSource source() {             if (bufferedSource == null) {                 bufferedSource = Okio.buffer(source(responseBody.source()));             }             return bufferedSource;         }         private Source source(Source source) {             return new ForwardingSource(source) {                 long totalBytesRead = 0L;                 @Override                 public long read(Buffer sink, long byteCount) throws IOException {                     long bytesRead = super.read(sink, byteCount);                     long fullLength = responseBody.contentLength();                     if (bytesRead == -1) { // this source is exhausted                         totalBytesRead = fullLength;                     } else {                         totalBytesRead += bytesRead;                     }                     progressListener.update(url, totalBytesRead, fullLength);                     return bytesRead;                 }             };         }     } }

    这里需要注意一下,需要延迟配置GlideModule,

    xml:

<!-- Glide与OkHttp3集成 --> <meta-data     android:name="com.example.lagerp_w_picpath_test.glide.OkHttpProgressGlideModule"     android:value="GlideModule" />

    onCreate:

final Glide glide = Glide.get(this); OkHttpProgressGlideModule a = new OkHttpProgressGlideModule(); a.registerComponents(this, glide);

    这里这样写的原因是在你加载图片的时候给加载的进度过程,自定义OkHttpProgressGlideModule,

    ProgressTarget:

package com.example.shining.p042_largep_w_picpath.glide37; import android.graphics.drawable.Drawable; import com.bumptech.glide.Glide; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.Target; public abstract class ProgressTarget<T, Z> extends WrappingTarget<Z> implements OkHttpProgressGlideModule.UIProgressListener {     private T model;     private boolean ignoreProgress = true;     public ProgressTarget(T model, Target<Z> target) {         super(target);         this.model = model;     }     public final T getModel() {         return model;     }     public final void setModel(T model) {         Glide.clear(this); // indirectly calls cleanup         this.model = model;     }     /**      * Convert a model into an Url string that is used to match up the OkHttp requests. For explicit      * {@link com.bumptech.glide.load.model.GlideUrl GlideUrl} loads this needs to return      * {@link com.bumptech.glide.load.model.GlideUrl#toStringUrl toStringUrl}. For custom models do the same as your      * {@link com.bumptech.glide.load.model.stream.BaseGlideUrlLoader BaseGlideUrlLoader} does.      *      * @param model return the representation of the given model, DO NOT use {@link #getModel()} inside this method.      * @return a stable Url representation of the model, otherwise the progress reporting won't work      */     protected String toUrlString(T model) {         return String.valueOf(model);     }     @Override     public float getGranualityPercentage() {         return 1.0f;     }     private void start() {         OkHttpProgressGlideModule.expect(toUrlString(model), this);         ignoreProgress = false;     }     private void cleanup() {         ignoreProgress = true;         T model = this.model; // save in case it gets modified         OkHttpProgressGlideModule.forget(toUrlString(model));         this.model = null;     }     @Override     public void onLoadStarted(Drawable placeholder) {         super.onLoadStarted(placeholder);         start();     }     @Override     public void onResourceReady(Z resource, GlideAnimation<? super Z> animation) {         cleanup();         super.onResourceReady(resource, animation);     }     @Override     public void onLoadFailed(Exception e, Drawable errorDrawable) {         cleanup();         super.onLoadFailed(e, errorDrawable);     }     @Override     public void onLoadCleared(Drawable placeholder) {         cleanup();         super.onLoadCleared(placeholder);     } }

    WrappingTarget:

package com.example.shining.p042_largep_w_picpath.glide37; import android.graphics.drawable.Drawable; import com.bumptech.glide.request.Request; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.SizeReadyCallback; import com.bumptech.glide.request.target.Target; public class WrappingTarget<Z> implements Target<Z> {     protected final Target<Z> target;     public WrappingTarget(Target<Z> target) {         this.target = target;     }     @Override     public void getSize(SizeReadyCallback cb) {         if (target != null)             target.getSize(cb);     }     @Override     public void onLoadStarted(Drawable placeholder) {         if (target != null)             target.onLoadStarted(placeholder);     }     @Override     public void onLoadFailed(Exception e, Drawable errorDrawable) {         if (target != null)             target.onLoadFailed(e, errorDrawable);     }     @Override     public void onResourceReady(Z resource, GlideAnimation<? super Z> glideAnimation) {         if (target != null)             target.onResourceReady(resource, glideAnimation);     }     @Override     public void onLoadCleared(Drawable placeholder) {         if (target != null) target.onLoadCleared(placeholder);     }     private Request request;     @Override     public Request getRequest() {         return request;     }     @Override     public void setRequest(Request request) {         this.request = request;         if (target != null)             target.setRequest(request);     }     @Override     public void onStart() {         if (target != null)             target.onStart();     }     @Override     public void onStop() {         if (target != null)             target.onStop();     }     @Override     public void onDestroy() {         if (target != null) target.onDestroy();     } }

    buildgradle:

//largep_w_picpath compile 'com.shizhefei:LargeImageView:1.0.9' compile 'com.github.HotBitmapGG:RingProgressBar:V1.2.2'

    加载网络图片MainActivityLargeImageGlide:

package com.example.shining.p042_largep_w_picpath.activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import com.bumptech.glide.Glide; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.SizeReadyCallback; import com.bumptech.glide.request.target.Target; import com.example.shining.p042_largep_w_picpath.R; import com.example.shining.p042_largep_w_picpath.glide37.OkHttpProgressGlideModule; import com.example.shining.p042_largep_w_picpath.glide37.ProgressTarget; import com.shizhefei.view.largep_w_picpath.LargeImageView; import com.shizhefei.view.largep_w_picpath.factory.FileBitmapDecoderFactory; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import io.netopen.hotbitmapgg.library.view.RingProgressBar; public class MainActivityLargeImageGlide extends AppCompatActivity {     private LargeImageView largeImageView;     private RingProgressBar ringProgressBar;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_large_p_w_picpath_view);         largeImageView = (LargeImageView) findViewById(R.id.networkDemo_photoView);         ringProgressBar = (RingProgressBar) findViewById(R.id.networkDemo_ringProgressBar); //        String url = "http://short.im.rockhippo.cn/uploads/msg/201703/20170309/1485/1489068660846.jpg"; //        URL fileUrl = null; //        File file = null; //        try { //            fileUrl = new URL(url); //            file = new File(fileUrl.toURI()); //        } catch (MalformedURLException | URISyntaxException e) { //            e.printStackTrace(); //        } // //        assert file != null; //        largeImageView.setImage(new FileBitmapDecoderFactory(file)); //        String url = "https://s2.51cto.com/wyfs02/M02/06/F4/wKiom1nA9iSRwF1BADe7ZVL2w4Q127.jpg"; //        String url = "https://s2.51cto.com/wyfs02/M00/06/F4/wKiom1nA-Aiy9qMkAAR3_qzZ1is031.jpg";         String url = "https://s3.51cto.com/wyfs02/M00/A5/A5/wKioL1nA-WrQ8NSkAADpAlDnsrM054.jpg";         final Glide glide = Glide.get(this);         OkHttpProgressGlideModule a = new OkHttpProgressGlideModule();         a.registerComponents(this, glide);         new Thread() {             @Override             public void run() {                 super.run();                 Glide.get(getApplicationContext()).clearDiskCache();                 runOnUiThread(new Runnable() {                     @Override                     public void run() { //                        Toast.makeText(getApplicationContext(), "清除缓存成功", Toast.LENGTH_SHORT).show();                     }                 });             }         }.start();         Glide.with(this).load(url).downloadOnly(new ProgressTarget<String, File>(url, null) {             @Override             public void onLoadStarted(Drawable placeholder) {                 super.onLoadStarted(placeholder);                 ringProgressBar.setVisibility(View.VISIBLE);                 ringProgressBar.setProgress(0);             }             @Override             public void onProgress(long bytesRead, long expectedLength) {                 int p = 0;                 if (expectedLength >= 0) {                     p = (int) (100 * bytesRead / expectedLength);                 }                 ringProgressBar.setProgress(p);             }             @Override             public void onResourceReady(File resource, GlideAnimation<? super File> animation) {                 super.onResourceReady(resource, animation);                 ringProgressBar.setVisibility(View.GONE); //                largeImageView.setEnabled(false);                 largeImageView.setImage(new FileBitmapDecoderFactory(resource));             }             @Override             public void getSize(SizeReadyCallback cb) {                 cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);             }         });     }     /**      * 根据图片的url路径获得Bitmap对象      *      * @param url      * @return      */     private Bitmap returnBitmap(String url) {         URL fileUrl = null;         Bitmap bitmap = null;         try {             fileUrl = new URL(url);         } catch (MalformedURLException e) {             e.printStackTrace();         }         try {             HttpURLConnection conn = (HttpURLConnection) fileUrl.openConnection();             conn.setDoInput(true);             conn.connect();             InputStream is = conn.getInputStream();             bitmap = BitmapFactory.decodeStream(is);             is.close();         } catch (IOException e) {             e.printStackTrace();         }         return bitmap;     } }

    加载本地assets文件夹大图,这里要说一下,经过测试,手机取drawable里面的巨图会OOM,平板不会,但是assets目录手机和平板都支持,因为drawable取的是路径加载,assets是文件流,所以不会OOM,

    加载drawable目录 MainActivityLargeImageLocal1:

package com.example.shining.p042_largep_w_picpath.activity; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import com.example.shining.p042_largep_w_picpath.R; import com.shizhefei.view.largep_w_picpath.LargeImageView; public class MainActivityLargeImageLocal1 extends AppCompatActivity {     private LargeImageView localDemo_photoView;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main_largep_w_picpath_local);         localDemo_photoView = (LargeImageView) findViewById(R.id.localDemo_photoView);         String fileName = getIntent().getStringExtra("file_name");         localDemo_photoView.setImage(getResources().getDrawable(R.drawable.qm3));         runOnUiThread(new Runnable() {             @Override             public void run() {                 localDemo_photoView.setScale(0.5f);             }         });     } }

    加载assets目录 MainActivityLargeImageLocal2:

package com.example.shining.p042_largep_w_picpath.activity; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import com.example.shining.p042_largep_w_picpath.R; import com.shizhefei.view.largep_w_picpath.BlockImageLoader; import com.shizhefei.view.largep_w_picpath.LargeImageView; import com.shizhefei.view.largep_w_picpath.factory.InputStreamBitmapDecoderFactory; import java.io.IOException; import java.io.InputStream; public class MainActivityLargeImageLocal2 extends AppCompatActivity {     private LargeImageView largeImageView;     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main_largep_w_picpath_local);         largeImageView = (LargeImageView) findViewById(R.id.localDemo_photoView);         try {             String fileName = getIntent().getStringExtra("file_name");             //通过文件的方式加载sd卡中的大图 //            localDemo_photoView.setImage(new FileBitmapDecoderFactory(file));             //通过流的方式加载assets文件夹里面的大图             InputStream inputStream = getAssets().open("qm.jpg");             largeImageView.setImage(new InputStreamBitmapDecoderFactory(inputStream)); //            localDemo_photoView.setImage(new InputStreamBitmapDecoderFactory(inputStream), getResources().getDrawable(R.drawable.mvc));             runOnUiThread(new Runnable() {                 @Override                 public void run() {                     largeImageView.setScale(0.5f);                     largeImageView.setOnImageLoadListener(new BlockImageLoader.OnImageLoadListener() {                         @Override                         public void onBlockImageLoadFinished() {                         }                         @Override                         public void onLoadImageSize(int p_w_picpathWidth, int p_w_picpathHeight) {                             String a = p_w_picpathHeight + "";                         }                         @Override                         public void onLoadFail(Exception e) {                         }                     }); //                    largeImageView.setCriticalScaleValueHook(new LargeImageView.CriticalScaleValueHook() { //                        @Override //                        public float getMinScale(LargeImageView largeImageView, int p_w_picpathWidth, int p_w_picpathHeight, float suggestMinScale) { //                            return 15; //                        } // //                        @Override //                        public float getMaxScale(LargeImageView largeImageView, int p_w_picpathWidth, int p_w_picpathHeight, float suggestMaxScale) { //                            return 30; //                        } //                    });                 }             });         } catch (IOException e) {             e.printStackTrace();         }     } }

    这里给你提供一下小细节,大部分人在后台返回色值或者UI设计0%透明度的时候烦恼,给大家记录一下透明的计算方法:

     <color name="transparent_white">#00ffffff</color>      00这两位的计算:255*50%(透明度UI会告诉你)=结果128转化成16进制就是80这两位你需要的。

    colorUtil:

<?xml version="1.0" encoding="utf-8"?> <resources>     <color name="colorPrimary">#3F51B5</color>     <color name="colorPrimaryDark">#303F9F</color>     <color name="colorAccent">#FF4081</color>     <color name="gray_line">#dfdfdf</color>     <color name="white">#ffffff</color>     <!-- 白色 -->     <color name="ivory">#fffff0</color>     <!-- 象牙色 -->     <color name="lightyellow">#ffffe0</color>     <!-- 亮××× -->     <color name="yellow">#ffff00</color>     <!-- ××× -->     <color name="snow">#fffafa</color>     <!-- 雪白色 -->     <color name="floralwhite">#fffaf0</color>     <!-- 花白色 -->     <color name="lemonchiffon">#fffacd</color>     <!-- 柠檬绸色 -->     <color name="cornsilk">#fff8dc</color>     <!-- 米绸色 -->     <color name="seaShell">#fff5ee</color>     <!-- 海贝色 -->     <color name="lavenderblush">#fff0f5</color>     <!-- 淡紫红 -->     <color name="papayawhip">#ffefd5</color>     <!-- 番木色 -->     <color name="blanchedalmond">#ffebcd</color>     <!-- 白杏色 -->     <color name="mistyrose">#ffe4e1</color>     <!-- 浅玫瑰色 -->     <color name="bisque">#ffe4c4</color>     <!-- 桔××× -->     <color name="moccasin">#ffe4b5</color>     <!-- 鹿皮色 -->     <color name="navajowhite">#ffdead</color>     <!-- 纳瓦白 -->     <color name="peachpuff">#ffdab9</color>     <!-- 桃色 -->     <color name="gold">#ffd700</color>     <!-- 金色 -->     <color name="pink">#ffc0cb</color>     <!-- 粉红色 -->     <color name="lightpink">#ffb6c1</color>     <!-- 亮粉红色 -->     <color name="orange">#ffa500</color>     <!-- 橙色 -->     <color name="lightsalmon">#ffa07a</color>     <!-- 亮肉色 -->     <color name="darkorange">#ff8c00</color>     <!-- 暗桔××× -->     <color name="coral">#ff7f50</color>     <!-- 珊瑚色 -->     <color name="hotpink">#ff69b4</color>     <!-- 热粉红色 -->     <color name="tomato">#ff6347</color>     <!-- 西红柿色 -->     <color name="orangered">#ff4500</color>     <!-- 红橙色 -->     <color name="deeppink">#ff1493</color>     <!-- 深粉红色 -->     <color name="fuchsia">#ff00ff</color>     <!-- 紫红色 -->     <color name="magenta">#ff00ff</color>     <!-- 红紫色 -->     <color name="red">#ff0000</color>     <!-- 红色 -->     <color name="oldlace">#fdf5e6</color>     <!-- 老花色 -->     <color name="lightgoldenrodyellow">#fafad2</color>     <!-- 亮金××× -->     <color name="linen">#faf0e6</color>     <!-- 亚麻色 -->     <color name="antiquewhite">#faebd7</color>     <!-- 古董白 -->     <color name="salmon">#fa8072</color>     <!-- 鲜肉色 -->     <color name="ghostwhite">#f8f8ff</color>     <!-- 幽灵白 -->     <color name="mintcream">#f5fffa</color>     <!-- 薄荷色 -->     <color name="whitesmoke">#f5f5f5</color>     <!-- 烟白色 -->     <color name="beige">#f5f5dc</color>     <!-- 米色 -->     <color name="wheat">#f5deb3</color>     <!-- 浅××× -->     <color name="sandybrown">#f4a460</color>     <!-- 沙褐色 -->     <color name="azure">#f0ffff</color>     <!-- 天蓝色 -->     <color name="honeydew">#f0fff0</color>     <!-- 蜜色 -->     <color name="aliceblue">#f0f8ff</color>     <!-- 艾利斯兰 -->     <color name="khaki">#f0e68c</color>     <!-- 黄褐色 -->     <color name="lightcoral">#f08080</color>     <!-- 亮珊瑚色 -->     <color name="palegoldenrod">#eee8aa</color>     <!-- 苍麒麟色 -->     <color name="violet">#ee82ee</color>     <!-- 紫罗兰色 -->     <color name="darksalmon">#e9967a</color>     <!-- 暗肉色 -->     <color name="lavender">#e6e6fa</color>     <!-- 淡紫色 -->     <color name="lightcyan">#e0ffff</color>     <!-- 亮青色 -->     <color name="burlywood">#deb887</color>     <!-- 实木色 -->     <color name="plum">#dda0dd</color>     <!-- 洋李色 -->     <color name="gainsboro">#dcdcdc</color>     <!-- 淡灰色 -->     <color name="crimson">#dc143c</color>     <!-- 暗深红色 -->     <color name="palevioletred">#db7093</color>     <!-- 苍紫罗兰色 -->     <color name="goldenrod">#daa520</color>     <!-- 金麒麟色 -->     <color name="orchid">#da70d6</color>     <!-- 淡紫色 -->     <color name="thistle">#d8bfd8</color>     <!-- 蓟色 -->     <color name="lightgray">#d3d3d3</color>     <!-- 亮灰色 -->     <color name="lightgrey">#d3d3d3</color>     <!-- 亮灰色 -->     <color name="tan">#d2b48c</color>     <!-- 茶色 -->     <color name="chocolate">#d2691e</color>     <!-- 巧可力色 -->     <color name="peru">#cd853f</color>     <!-- 秘鲁色 -->     <color name="indianred">#cd5c5c</color>     <!-- 印第安红 -->     <color name="mediumvioletred">#c71585</color>     <!-- 中紫罗兰色 -->     <color name="silver">#c0c0c0</color>     <!-- 银色 -->     <color name="darkkhaki">#bdb76b</color>     <!-- 暗黄褐色 -->     <color name="rosybrown">#bc8f8f</color>     <!-- 褐玫瑰红 -->     <color name="mediumorchid">#ba55d3</color>     <!-- 中粉紫色 -->     <color name="darkgoldenrod">#b8860b</color>     <!-- 暗金××× -->     <color name="firebrick">#b22222</color>     <!-- 火砖色 -->     <color name="powderblue">#b0e0e6</color>     <!-- 粉蓝色 -->     <color name="lightsteelblue">#b0c4de</color>     <!-- 亮钢兰色 -->     <color name="paleturquoise">#afeeee</color>     <!-- 苍宝石绿 -->     <color name="greenyellow">#adff2f</color>     <!-- 黄绿色 -->     <color name="lightblue">#add8e6</color>     <!-- 亮蓝色 -->     <color name="darkgray">#a9a9a9</color>     <!-- 暗灰色 -->     <color name="darkgrey">#a9a9a9</color>     <!-- 暗灰色 -->     <color name="brown">#a52a2a</color>     <!-- 褐色 -->     <color name="sienna">#a0522d</color>     <!-- 赭色 -->     <color name="darkorchid">#9932cc</color>     <!-- 暗紫色 -->     <color name="palegreen">#98fb98</color>     <!-- 苍绿色 -->     <color name="darkviolet">#9400d3</color>     <!-- 暗紫罗兰色 -->     <color name="mediumpurple">#9370db</color>     <!-- 中紫色 -->     <color name="lightgreen">#90ee90</color>     <!-- 亮绿色 -->     <color name="darkseagreen">#8fbc8f</color>     <!-- 暗海兰色 -->     <color name="saddlebrown">#8b4513</color>     <!-- 重褐色 -->     <color name="darkmagenta">#8b008b</color>     <!-- 暗洋红 -->     <color name="darkred">#8b0000</color>     <!-- 暗红色 -->     <color name="blueviolet">#8a2be2</color>     <!-- 紫罗兰蓝色 -->     <color name="lightskyblue">#87cefa</color>     <!-- 亮天蓝色 -->     <color name="skyblue">#87ceeb</color>     <!-- 天蓝色 -->     <color name="gray">#808080</color>     <!-- 灰色 -->     <color name="grey">#808080</color>     <!-- 灰色 -->     <color name="olive">#808000</color>     <!-- 橄榄色 -->     <color name="purple">#800080</color>     <!-- 紫色 -->     <color name="maroon">#800000</color>     <!-- 粟色 -->     <color name="aquamarine">#7fffd4</color>     <!-- 碧绿色 -->     <color name="chartreuse">#7fff00</color>     <!-- 黄绿色 -->     <color name="lawngreen">#7cfc00</color>     <!-- 草绿色 -->     <color name="mediumslateblue">#7b68ee</color>     <!-- 中暗蓝色 -->     <color name="lightslategray">#778899</color>     <!-- 亮蓝灰 -->     <color name="lightslategrey">#778899</color>     <!-- 亮蓝灰 -->     <color name="slategray">#708090</color>     <!-- 灰石色 -->     <color name="slategrey">#708090</color>     <!-- 灰石色 -->     <color name="olivedrab">#6b8e23</color>     <!-- 深绿褐色 -->     <color name="slateblue">#6a5acd</color>     <!-- 石蓝色 -->     <color name="dimgray">#696969</color>     <!-- 暗灰色 -->     <color name="dimgrey">#696969</color>     <!-- 暗灰色 -->     <color name="mediumaquamarine">#66cdaa</color>     <!-- 中绿色 -->     <color name="cornflowerblue">#6495ed</color>     <!-- 菊兰色 -->     <color name="cadetblue">#5f9ea0</color>     <!-- 军兰色 -->     <color name="darkolivegreen">#556b2f</color>     <!-- 暗橄榄绿 -->     <color name="indigo">#4b0082</color>     <!-- 靛青色 -->     <color name="mediumturquoise">#48d1cc</color>     <!-- 中绿宝石 -->     <color name="darkslateblue">#483d8b</color>     <!-- 暗灰蓝色 -->     <color name="steelblue">#4682b4</color>     <!-- 钢兰色 -->     <color name="royalblue">#4169e1</color>     <!-- ×××蓝 -->     <color name="turquoise">#40e0d0</color>     <!-- 青绿色 -->     <color name="mediumseagreen">#3cb371</color>     <!-- 中海蓝 -->     <color name="limegreen">#32cd32</color>     <!-- 橙绿色 -->     <color name="darkslategray">#2f4f4f</color>     <!-- 暗瓦灰色 -->     <color name="darkslategrey">#2f4f4f</color>     <!-- 暗瓦灰色 -->     <color name="seagreen">#2e8b57</color>     <!-- 海绿色 -->     <color name="forestgreen">#228b22</color>     <!-- 森林绿 -->     <color name="lightseagreen">#20b2aa</color>     <!-- 亮海蓝色 -->     <color name="dodgerblue">#1e90ff</color>     <!-- 闪兰色 -->     <color name="midnightblue">#191970</color>     <!-- 中灰兰色 -->     <color name="aqua">#00ffff</color>     <!-- 浅绿色 -->     <color name="cyan">#00ffff</color>     <!-- 青色 -->     <color name="springgreen">#00ff7f</color>     <!-- 春绿色 -->     <color name="lime">#00ff00</color>     <!-- 酸橙色 -->     <color name="mediumspringgreen">#00fa9a</color>     <!-- 中春绿色 -->     <color name="darkturquoise">#00ced1</color>     <!-- 暗宝石绿 -->     <color name="deepskyblue">#00bfff</color>     <!-- 深天蓝色 -->     <color name="darkcyan">#008b8b</color>     <!-- 暗青色 -->     <color name="teal">#008080</color>     <!-- 水鸭色 -->     <color name="green">#008000</color>     <!-- 绿色 -->     <color name="darkgreen">#006400</color>     <!-- 暗绿色 -->     <color name="blue">#0000ff</color>     <!-- 蓝色 -->     <color name="mediumblue">#0000cd</color>     <!-- 中兰色 -->     <color name="darkblue">#00008b</color>     <!-- 暗蓝色 -->     <color name="navy">#000080</color>     <!-- 海军色 -->     <color name="black">#000000</color>     <!-- 黑色 -->     <color name="transparent">#0000</color>     <!-- 透明 -->     <color name="transparent2">#8000</color>     <!-- 透明 -->     <color name="style_red">#ff4c41</color>     <color name="style_divider_color">#C9C7CD</color>    <!-- common -->     <color name="c0">#ff000000</color>     <color name="c1">#D9000000</color>     <color name="c2">#8C000000</color>     <color name="c3">#66000000</color>     <color name="c4">#1A000000</color>     <color name="c5">#C34A42</color>     <color name="c6">#FF9800</color>     <color name="c7">#009734</color>     <color name="c8">#46AE36</color>     <color name="c9">#47B000</color>     <color name="c10">#007AFF</color>     <color name="c11">#1194F6</color>     <color name="c12">#9D1BB2</color>     <color name="transparent">#00000000</color>     <color name="transparent05">#0B000000</color>     <color name="transparent10">#1A000000</color>     <color name="transparent20">#33000000</color>     <color name="transparent30">#4D000000</color>     <color name="transparent40">#66000000</color>     <color name="transparent50">#80000000</color>     <color name="transparent60">#9A000000</color>     <color name="transparent70">#B3000000</color>     <color name="transparent80">#CC000000</color>     <color name="transparent90">#E5000000</color>     <color name="transparent100">#FF000000</color>     <color name="transparent_white">#00ffffff</color>     <color name="transparent10_white">#1Affffff</color>     <color name="transparent20_white">#33ffffff</color>     <color name="transparent30_white">#4Dffffff</color>     <color name="transparent40_white">#66ffffff</color>     <color name="transparent50_white">#80ffffff</color>     <color name="transparent60_white">#9Affffff</color>     <color name="transparent70_white">#B3ffffff</color>     <color name="transparent80_white">#CCffffff</color>     <color name="transparent90_white">#E5ffffff</color>     <color name="transparent100_white">#FFffffff</color>     <color name="placeholder_color">#1A000000</color>     <color name="white">#FFFFFF</color>  <!-- 白色 -->     <color name="yellow">#fbc02d</color> <!-- ××× -->     <color name="gold">#FFD700</color>   <!-- 金色 -->     <color name="orange">#f57c00</color> <!-- 橙色 -->     <color name="red">#d01716</color>    <!-- 红色 -->     <color name="gray">#808080</color>   <!-- 灰色 -->     <color name="green">#0a7e07</color>  <!-- 绿色 -->     <color name="blue">#455ede</color>   <!-- 蓝色 -->     <color name="black">#000000</color>  <!-- 黑色 --> </resources>

    接着是Glide4.1.1的用法

    首先我把开源的代码总结出来了一个library,大家可以打成aarjar或者直接引用,下面介绍用法我是直接引用,建议大家以后打成aar方便,

    glide411library的build.gradle:

compile 'com.android.support:support-v4:26.0.0-alpha1' compile 'com.github.bumptech.glide:glide:4.1.1' compile 'com.github.bumptech.glide:compiler:4.1.1' compile "com.github.bumptech.glide:okhttp3-integration:4.1.1"

    glide411library这里就不贴代码了,给大家提供地址,大家去使用:

    https://github.com/geeklx/MyApplication/tree/master/glide411library

    自己的项目使用glide411以及支持大图功能 build.gradle:

compile 'com.android.support:appcompat-v7:26.0.0-alpha1' compile 'com.android.support:percent:26.0.0-alpha1' compile 'com.android.support:design:26.0.0-alpha1' compile 'com.android.support.constraint:constraint-layout:1.0.2' //glide411 compile 'com.github.chrisbanes:PhotoView:2.1.3' compile project(':glide411library') //largep_w_picpath compile 'com.github.bumptech.glide:glide:4.1.1' compile 'com.github.bumptech.glide:compiler:4.1.1' compile "com.github.bumptech.glide:okhttp3-integration:4.1.1" compile 'com.shizhefei:LargeImageView:1.0.9' compile 'com.github.HotBitmapGG:RingProgressBar:V1.2.2'

    首先是glidedemo411的基础使用,应该是网上目前见过的最全的吧,我猜~哈哈哈~反正所有的方法我都总结出来了,漏的话不负责~哈哈~

    SingleImageActivity:(预览图Activity)

package com.example.shining.p041_glide411.glidedemo411.p_w_picpath; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Toast; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; import com.bumptech.glide.request.RequestOptions; import com.example.shining.glide411library.progress.CircleProgressView; import com.example.shining.glide411library.progress.OnGlideImageViewListener; import com.example.shining.glide411library.view.GlideImageLoader; import com.example.shining.glide411library.view.GlideImageView; import com.example.shining.p041_glide411.R; import java.util.Random; public class SingleImageActivity extends AppCompatActivity {     GlideImageView glideImageView;     CircleProgressView progressView;     CircleProgressView progressView1;     CircleProgressView progressView2;     CircleProgressView progressView3;     View maskView;     public static final String KEY_IMAGE_URL = "p_w_picpath_url";     public static final String KEY_IMAGE_URL_THUMBNAIL = "p_w_picpath_url_thumbnail";     String p_w_picpath_url;     String p_w_picpath_url_thumbnail;     @Override     protected void onCreate(@Nullable Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main_glide411_p_w_picpath);         glideImageView = (GlideImageView) findViewById(R.id.glideImageView);         progressView1 = (CircleProgressView) findViewById(R.id.progressView1);         progressView2 = (CircleProgressView) findViewById(R.id.progressView2);         progressView3 = (CircleProgressView) findViewById(R.id.progressView3);         maskView = findViewById(R.id.maskView);         p_w_picpath_url = getIntent().getStringExtra(KEY_IMAGE_URL);         p_w_picpath_url_thumbnail = getIntent().getStringExtra(KEY_IMAGE_URL_THUMBNAIL);         initProgressView();         loadImage();     }     private void initProgressView() { //        MainActivityGlide.isLoadAgain = new Random().nextInt(3) == 1;         int randomNum = new Random().nextInt(3);         switch (randomNum) {             case 1:                 progressView = progressView2;                 break;             case 2:                 progressView = progressView3;                 break;             case 0:             default:                 progressView = progressView1;                 break;         }         progressView1.setVisibility(View.GONE);         progressView2.setVisibility(View.GONE);         progressView3.setVisibility(View.GONE);         progressView.setVisibility(View.VISIBLE);     }     private void loadImage() {         glideImageView.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 ActivityCompat.finishAfterTransition(SingleImageActivity.this);             }         });         RequestOptions requestOptions = glideImageView.requestOptions(R.color.black)                 .centerCrop();         RequestOptions requestOptionsWithoutCache = glideImageView.requestOptions(R.color.black)                 .centerCrop()                 .skipMemoryCache(true)                 .diskCacheStrategy(DiskCacheStrategy.NONE);         GlideImageLoader p_w_picpathLoader = glideImageView.getImageLoader();         p_w_picpathLoader.setOnGlideImageViewListener(p_w_picpath_url, new OnGlideImageViewListener() {             @Override             public void onProgress(int percent, boolean isDone, GlideException exception) {                 if (exception != null && !TextUtils.isEmpty(exception.getMessage())) {                     Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();                 }                 progressView.setProgress(percent);                 Log.d("--->p_w_picpathLoader", "percent: " + percent + " isDone: " + isDone);                 progressView.setVisibility(isDone ? View.GONE : View.VISIBLE);                 maskView.setVisibility(isDone ? View.GONE : View.VISIBLE);             }         });         p_w_picpathLoader.requestBuilder(p_w_picpath_url, requestOptionsWithoutCache)                 .thumbnail(Glide.with(SingleImageActivity.this)                         .load(p_w_picpath_url_thumbnail)                         .apply(requestOptions))                 .transition(DrawableTransitionOptions.withCrossFade())                 .into(glideImageView);     } }

    MainActivityGlide:(411demo Activity)

package com.example.shining.p041_glide411.glidedemo411; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityOptionsCompat; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Toast; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.GlideException; import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; import com.bumptech.glide.request.RequestOptions; import com.example.shining.glide411library.progress.CircleProgressView; import com.example.shining.glide411library.progress.OnGlideImageViewListener; import com.example.shining.glide411library.progress.OnProgressListener; import com.example.shining.glide411library.view.GlideImageLoader; import com.example.shining.glide411library.view.GlideImageView; import com.example.shining.glide411library.view.ShapeImageView; import com.example.shining.p041_glide411.R; import com.example.shining.p041_glide411.glidedemo411.p_w_picpath.SingleImageActivity; import java.util.Random; import static com.example.shining.p041_glide411.glidedemo411.p_w_picpath.SingleImageActivity.KEY_IMAGE_URL; import static com.example.shining.p041_glide411.glidedemo411.p_w_picpath.SingleImageActivity.KEY_IMAGE_URL_THUMBNAIL; public class MainActivityGlide extends AppCompatActivity {     private GlideImageView p_w_picpath11;     private GlideImageView p_w_picpath12;     private GlideImageView p_w_picpath13;     private GlideImageView p_w_picpath14;     private String url1 = "https://s3.51cto.com/wyfs02/M01/89/BA/wKioL1ga-u7QnnVnAAAfrCiGnBQ946_middle.jpg";     private GlideImageView p_w_picpath21;     private GlideImageView p_w_picpath22;     private GlideImageView p_w_picpath23;     private GlideImageView p_w_picpath24;     private GlideImageView p_w_picpath31;     private GlideImageView p_w_picpath32;     private GlideImageView p_w_picpath33;     private GlideImageView p_w_picpath34;     private String gif1 = "https://timgsa.baidu.com/timg?p_w_picpath&quality=80&size=b9999_10000&sec=1505394298896&di=98e0e804231a282ef80360e94fa7dca6&imgtype=0&src=http%3A%2F%2Fimg.qqai.net%2Fuploads%2Fi_3_2854471891x1596414192_21.jpg";     private GlideImageView p_w_picpath41;     private CircleProgressView progressView1;     private String p_w_picpath41BigUrl = "https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1232.png";     private String p_w_picpath41SmallUrl = "https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1231.png";     private GlideImageView p_w_picpath42;     private CircleProgressView progressView2;     private String p_w_picpath42BigUrl = "https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1234.png";     private String p_w_picpath42SmallUrl = "https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1233.png";     public static boolean isLoadAgain = false; // Just for fun when loading p_w_picpaths!     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main_glide411);         //Glide         findview();         isLoadAgain = new Random().nextInt(3) == 1;         line1();         line2();         line3();         line41();         line42();     }     private void findview() {         p_w_picpath11 = (GlideImageView) findViewById(R.id.p_w_picpath11);         p_w_picpath12 = (GlideImageView) findViewById(R.id.p_w_picpath12);         p_w_picpath13 = (GlideImageView) findViewById(R.id.p_w_picpath13);         p_w_picpath14 = (GlideImageView) findViewById(R.id.p_w_picpath14);         p_w_picpath21 = (GlideImageView) findViewById(R.id.p_w_picpath21);         p_w_picpath22 = (GlideImageView) findViewById(R.id.p_w_picpath22);         p_w_picpath23 = (GlideImageView) findViewById(R.id.p_w_picpath23);         p_w_picpath24 = (GlideImageView) findViewById(R.id.p_w_picpath24);         p_w_picpath31 = (GlideImageView) findViewById(R.id.p_w_picpath31);         p_w_picpath32 = (GlideImageView) findViewById(R.id.p_w_picpath32);         p_w_picpath33 = (GlideImageView) findViewById(R.id.p_w_picpath33);         p_w_picpath34 = (GlideImageView) findViewById(R.id.p_w_picpath34);         p_w_picpath41 = (GlideImageView) findViewById(R.id.p_w_picpath41);         progressView1 = (CircleProgressView) findViewById(R.id.progressView1);         p_w_picpath42 = (GlideImageView) findViewById(R.id.p_w_picpath42);         progressView2 = (CircleProgressView) findViewById(R.id.progressView2);     }     private void line41() {         p_w_picpath41.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 Intent intent = new Intent(MainActivityGlide.this, SingleImageActivity.class);                 intent.putExtra(KEY_IMAGE_URL, p_w_picpath41BigUrl);                 intent.putExtra(KEY_IMAGE_URL_THUMBNAIL, p_w_picpath41SmallUrl);                 ActivityOptionsCompat compat = ActivityOptionsCompat                         .makeSceneTransitionAnimation(MainActivityGlide.this, p_w_picpath41, getString(R.string.transitional_p_w_picpath));                 ActivityCompat.startActivity(MainActivityGlide.this, intent, compat.toBundle());             }         });         RequestOptions requestOptions = p_w_picpath41.requestOptions(R.color.placeholder_color).centerCrop();         if (isLoadAgain) {             requestOptions.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true);         }         // 第一种方式加载         p_w_picpath41.load(p_w_picpath41SmallUrl, requestOptions).listener(new OnGlideImageViewListener() {             @Override             public void onProgress(int percent, boolean isDone, GlideException exception) {                 if (exception != null && !TextUtils.isEmpty(exception.getMessage())) {                     Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();                 }                 progressView1.setProgress(percent);                 progressView1.setVisibility(isDone ? View.GONE : View.VISIBLE);             }         });     }     private void line42() {         p_w_picpath42.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 Intent intent = new Intent(MainActivityGlide.this, SingleImageActivity.class);                 intent.putExtra(KEY_IMAGE_URL, p_w_picpath42BigUrl);                 intent.putExtra(KEY_IMAGE_URL_THUMBNAIL, p_w_picpath42BigUrl);                 ActivityOptionsCompat compat = ActivityOptionsCompat                         .makeSceneTransitionAnimation(MainActivityGlide.this, p_w_picpath42, getString(R.string.transitional_p_w_picpath));                 ActivityCompat.startActivity(MainActivityGlide.this, intent, compat.toBundle());             }         });         RequestOptions requestOptions = p_w_picpath42.requestOptions(R.color.placeholder_color).centerCrop();         if (isLoadAgain) {             requestOptions.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true);         }         // 第二种方式加载:可以解锁更多功能         GlideImageLoader p_w_picpathLoader = p_w_picpath42.getImageLoader();         p_w_picpathLoader.setOnGlideImageViewListener(p_w_picpath42SmallUrl, new OnGlideImageViewListener() {             @Override             public void onProgress(int percent, boolean isDone, GlideException exception) {                 if (exception != null && !TextUtils.isEmpty(exception.getMessage())) {                     Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();                 }                 progressView2.setProgress(percent);                 progressView2.setVisibility(isDone ? View.GONE : View.VISIBLE);             }         });         p_w_picpathLoader.requestBuilder(p_w_picpath42SmallUrl, requestOptions)                 .transition(DrawableTransitionOptions.withCrossFade())                 .into(p_w_picpath42);     }     private void line3() {         p_w_picpath31.loadLocalImage(R.drawable.gif_robot_walk, R.drawable.ic_def_loading);         p_w_picpath32.loadCircleImage(gif1, R.mipmap.ic_launcher).listener(new OnGlideImageViewListener() {             @Override             public void onProgress(int percent, boolean isDone, GlideException exception) {                 Log.d("--->p_w_picpath32", "percent: " + percent + " isDone: " + isDone);             }         });         p_w_picpath33.loadImage(gif1, R.drawable.ic_def_loading);         p_w_picpath34.loadImage(gif1, R.drawable.ic_def_loading);     }     private void line2() {         p_w_picpath21.loadImage(url1, R.drawable.ic_def_loading);         p_w_picpath22.loadImage("", R.drawable.ic_def_loading);         p_w_picpath23.loadImage(url1, R.color.placeholder_color);         p_w_picpath24.loadImage(url1, R.color.placeholder_color);     }     private void line1() {         p_w_picpath11.loadImage(url1, R.color.black).listener(new OnProgressListener() {             @Override             public void onProgress(String p_w_picpathUrl, long bytesRead, long totalBytes, boolean isDone, GlideException exception) {                 Log.d("--->p_w_picpath11", "bytesRead: " + bytesRead + " totalBytes: " + totalBytes + " isDone: " + isDone);             }         });         p_w_picpath12.setShapeType(ShapeImageView.ShapeType.CIRCLE);         p_w_picpath12.setBorderWidth(3);         p_w_picpath12.setBorderColor(R.color.transparent20);         p_w_picpath12.loadCircleImage(url1, R.color.black);         p_w_picpath12.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View view) {                 Toast.makeText(MainActivityGlide.this, "p_w_picpath12", Toast.LENGTH_SHORT).show();             }         });         p_w_picpath13.setShapeType(ShapeImageView.ShapeType.RECTANGLE);         p_w_picpath13.setRadius(15);         p_w_picpath13.setBorderWidth(3);         p_w_picpath13.setBorderColor(R.color.blue);         p_w_picpath13.setPressedAlpha(0.3f);         p_w_picpath13.setPressedColor(R.color.blue);         p_w_picpath13.loadImage(url1, R.color.placeholder_color);         p_w_picpath14.setShapeType(ShapeImageView.ShapeType.CIRCLE);         p_w_picpath14.setBorderWidth(3);         p_w_picpath14.setBorderColor(R.color.blue);         p_w_picpath14.setPressedAlpha(0.2f);         p_w_picpath14.setPressedColor(R.color.black);         p_w_picpath14.loadImage(url1, R.color.placeholder_color);     } }

    接下来是largep_w_picpath:(用法跟glide3.7一样,我做了兼容,把兼容的代码给大家共享出来,用法看上面的glide3.7)。

    LargeImageViewTarget:

package com.example.shining.p041_glide411.largep_w_picpath.glide411; import android.graphics.drawable.Drawable; import android.view.View; import com.bumptech.glide.request.transition.Transition; import com.bumptech.glide.request.target.ViewTarget; import com.shizhefei.view.largep_w_picpath.ILargeImageView; import com.shizhefei.view.largep_w_picpath.factory.FileBitmapDecoderFactory; import java.io.File; /**  * A base {@link com.bumptech.glide.request.target.Target} for displaying resources in  * {@link android.widget.ImageView}s.  *  * @param <Z> The type of resource that this target will display in the wrapped {@link android.widget.ImageView}.  */ public class LargeImageViewTarget extends ViewTarget<View, File>{     private ILargeImageView largeImageView;     public <V extends View & ILargeImageView> LargeImageViewTarget(V view) {         super(view);         this.largeImageView = view;     }     /**      * Sets the given {@link Drawable} on the view using      * {@link android.widget.ImageView#setImageDrawable(Drawable)}.      *      * @param placeholder {@inheritDoc}      */     @Override     public void onLoadStarted(Drawable placeholder) {         largeImageView.setImageDrawable(placeholder);     }     /**      * Sets the given {@link Drawable} on the view using      * {@link android.widget.ImageView#setImageDrawable(Drawable)}.      *      * @param errorDrawable {@inheritDoc}      */     @Override     public void onLoadFailed(Drawable errorDrawable) {         largeImageView.setImageDrawable(errorDrawable);     }     @Override     public void onResourceReady(File resource, Transition<? super File> glideAnimation) {         largeImageView.setImage(new FileBitmapDecoderFactory(resource));     }     /**      * Sets the given {@link Drawable} on the view using      * {@link android.widget.ImageView#setImageDrawable(Drawable)}.      *      * @param placeholder {@inheritDoc}      */     @Override     public void onLoadCleared(Drawable placeholder) {         largeImageView.setImageDrawable(placeholder);     } }

    OkHttpProgressGlideModule:

package com.example.shining.p041_glide411.largep_w_picpath.glide411; import android.content.Context; import android.os.Handler; import android.os.Looper; import com.bumptech.glide.Glide; import com.bumptech.glide.GlideBuilder; import com.bumptech.glide.Registry; import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; import com.bumptech.glide.load.model.GlideUrl; import com.bumptech.glide.module.AppGlideModule; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import okio.Buffer; import okio.BufferedSource; import okio.ForwardingSource; import okio.Okio; import okio.Source; // TODO add <meta-data android:value="GlideModule" android:name="....OkHttpProgressGlideModule" /> // TODO add <meta-data android:value="GlideModule" tools:node="remove" android:name="com.bumptech.glide.integration.okhttp.OkHttpGlideModule" /> // or not use 'okhttp@aar' in Gradle depdendencies public class OkHttpProgressGlideModule extends AppGlideModule {     @Override     public void applyOptions(Context context, GlideBuilder builder) {     }     @Override     public void registerComponents(Context context, Glide glide, Registry registry) {         super.registerComponents(context, glide, registry);         OkHttpClient.Builder builder = new OkHttpClient.Builder();         builder.networkInterceptors().add(createInterceptor(new DispatchingProgressListener()));         glide.getRegistry().append(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(builder.build())); //        glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(builder.build()));     }     private static Interceptor createInterceptor(final ResponseProgressListener listener) {         return new Interceptor() {             @Override             public Response intercept(Chain chain) throws IOException {                 Request request = chain.request();                 Response response = chain.proceed(request);                 return response.newBuilder()                         .body(new OkHttpProgre***esponseBody(request.url(), response.body(), listener))                         .build();             }         };     }     public interface UIProgressListener {         void onProgress(long bytesRead, long expectedLength);         /**          * Control how often the listener needs an update. 0% and 100% will always be dispatched.          *          * @return in percentage (0.2 = call {@link #onProgress} around every 0.2 percent of progress)          */         float getGranualityPercentage();     }     public static void forget(String url) {         DispatchingProgressListener.forget(url);     }     public static void expect(String url, UIProgressListener listener) {         DispatchingProgressListener.expect(url, listener);     }     private interface ResponseProgressListener {         void update(HttpUrl url, long bytesRead, long contentLength);     }     private static class DispatchingProgressListener implements ResponseProgressListener {         private static final Map<String, UIProgressListener> LISTENERS = new ConcurrentHashMap<>();         private static final Map<String, Long> PROGRESSES = new ConcurrentHashMap<>();         private final Handler handler;         DispatchingProgressListener() {             this.handler = new Handler(Looper.getMainLooper());         }         static void forget(String url) {             LISTENERS.remove(url);             PROGRESSES.remove(url);         }         static void expect(String url, UIProgressListener listener) {             LISTENERS.put(url, listener);         }         @Override         public void update(HttpUrl url, final long bytesRead, final long contentLength) {             //System.out.printf("%s: %d/%d = %.2f%%%n", url, bytesRead, contentLength, (100f * bytesRead) / contentLength);             String key = url.toString();             final UIProgressListener listener = LISTENERS.get(key);             if (listener == null) {                 return;             }             //长度是错误的移除监听             if (contentLength <= bytesRead) {                 forget(key);             }             if (needsDispatch(key, bytesRead, contentLength, listener.getGranualityPercentage())) {                 handler.post(new Runnable() {                     @Override                     public void run() {                         listener.onProgress(bytesRead, contentLength);                     }                 });             }         }         private boolean needsDispatch(String key, long current, long total, float granularity) {             if (granularity == 0 || current == 0 || total == current) {                 return true;             }             float percent = 100f * current / total;             long currentProgress = (long) (percent / granularity);             Long lastProgress = PROGRESSES.get(key);             if (lastProgress == null || currentProgress != lastProgress) {                 PROGRESSES.put(key, currentProgress);                 return true;             } else {                 return false;             }         }     }     private static class OkHttpProgre***esponseBody extends ResponseBody {         private final HttpUrl url;         private final ResponseBody responseBody;         private final ResponseProgressListener progressListener;         private BufferedSource bufferedSource;         OkHttpProgre***esponseBody(HttpUrl url, ResponseBody responseBody,                                    ResponseProgressListener progressListener) {             this.url = url;             this.responseBody = responseBody;             this.progressListener = progressListener;         }         @Override         public MediaType contentType() {             return responseBody.contentType();         }         @Override         public long contentLength() {             return responseBody.contentLength();         }         @Override         public BufferedSource source() {             if (bufferedSource == null) {                 bufferedSource = Okio.buffer(source(responseBody.source()));             }             return bufferedSource;         }         private Source source(Source source) {             return new ForwardingSource(source) {                 long totalBytesRead = 0L;                 @Override                 public long read(Buffer sink, long byteCount) throws IOException {                     long bytesRead = super.read(sink, byteCount);                     long fullLength = responseBody.contentLength();                     if (bytesRead == -1) { // this source is exhausted                         totalBytesRead = fullLength;                     } else {                         totalBytesRead += bytesRead;                     }                     progressListener.update(url, totalBytesRead, fullLength);                     return bytesRead;                 }             };         }     } }

    ProgressTarget:

package com.example.shining.p041_glide411.largep_w_picpath.glide411; import android.graphics.drawable.Drawable; import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import com.example.shining.p041_glide411.application.DemoApplication; public abstract class ProgressTarget<T, Z> extends WrappingTarget<Z> implements OkHttpProgressGlideModule.UIProgressListener {     private T model;     private boolean ignoreProgress = true;     public ProgressTarget(T model, Target<Z> target) {         super(target);         this.model = model;     }     public final T getModel() {         return model;     }     public final void setModel(T model) { //        Glide.clear(this); // indirectly calls cleanup         Glide.with(DemoApplication.mContext).clear(this);         this.model = model;     }     /**      * Convert a model into an Url string that is used to match up the OkHttp requests. For explicit      * {@link com.bumptech.glide.load.model.GlideUrl GlideUrl} loads this needs to return      * {@link com.bumptech.glide.load.model.GlideUrl#toStringUrl toStringUrl}. For custom models do the same as your      * {@link com.bumptech.glide.load.model.stream.BaseGlideUrlLoader BaseGlideUrlLoader} does.      *      * @param model return the representation of the given model, DO NOT use {@link #getModel()} inside this method.      * @return a stable Url representation of the model, otherwise the progress reporting won't work      */     protected String toUrlString(T model) {         return String.valueOf(model);     }     @Override     public float getGranualityPercentage() {         return 1.0f;     }     private void start() {         OkHttpProgressGlideModule.expect(toUrlString(model), this);         ignoreProgress = false;     }     private void cleanup() {         ignoreProgress = true;         T model = this.model; // save in case it gets modified         OkHttpProgressGlideModule.forget(toUrlString(model));         this.model = null;     }     @Override     public void onLoadStarted(Drawable placeholder) {         super.onLoadStarted(placeholder);         start();     }     @Override     public void onResourceReady(Z resource, Transition<? super Z> animation) {         cleanup();         super.onResourceReady(resource, animation);     }     @Override     public void onLoadFailed(Drawable errorDrawable) {         cleanup();         super.onLoadFailed(errorDrawable);     }     @Override     public void onLoadCleared(Drawable placeholder) {         cleanup();         super.onLoadCleared(placeholder);     } }

    WrappingTarget:

package com.example.shining.p041_glide411.largep_w_picpath.glide411; import android.graphics.drawable.Drawable; import android.support.annotation.Nullable; import com.bumptech.glide.request.Request; import com.bumptech.glide.request.target.SizeReadyCallback; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; public class WrappingTarget<Z> implements Target<Z> {     protected final Target<Z> target;     public WrappingTarget(Target<Z> target) {         this.target = target;     }     @Override     public void getSize(SizeReadyCallback cb) {         if (target != null)             target.getSize(cb);     }     @Override     public void removeCallback(SizeReadyCallback cb) {     }     @Override     public void onLoadStarted(Drawable placeholder) {         if (target != null)             target.onLoadStarted(placeholder);     }     @Override     public void onLoadFailed(@Nullable Drawable errorDrawable) {         if (target != null)             target.onLoadFailed(errorDrawable);     }     @Override     public void onResourceReady(Z resource, Transition<? super Z> glideAnimation) {         if (target != null)             target.onResourceReady(resource, glideAnimation);     }     @Override     public void onLoadCleared(Drawable placeholder) {         if (target != null) target.onLoadCleared(placeholder);     }     private Request request;     @Override     public Request getRequest() {         return request;     }     @Override     public void setRequest(Request request) {         this.request = request;         if (target != null)             target.setRequest(request);     }     @Override     public void onStart() {         if (target != null)             target.onStart();     }     @Override     public void onStop() {         if (target != null)             target.onStop();     }     @Override     public void onDestroy() {         if (target != null) target.onDestroy();     } }

    权限别忘了:

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    效果如下图:

    图1:

    wKiom1nDMjmzcZXAAAjWFI3-mhA983.gif

    图2:    

    wKioL1nDM5WQIlfjAAgKDZ4wp4Y993.gif

    图3:

    wKioL1nDM57RpIuaABGqn-ozXQY208.gif

    图4:

    wKiom1nDNGOAEwxIABTEoLfPDK8361.gif  

    今天介绍了很多东西,希望能帮到你~谢谢~

    附:

    glide3.7的地址:https://github.com/geeklx/MyApplication/tree/master/p042_largep_w_picpath

    glide4.1.1的地址:https://github.com/geeklx/MyApplication/tree/master/p041_glide411

    glide3.7图片加载地址:

    https://github.com/geeklx/MyApplication/tree/master/P009_Glide图片缓存

    glide4.1.1图片加载地址:

    https://github.com/geeklx/MyApplication/tree/master/p009_glide图片缓存411

    wKiom1nDOqrxffvCAAMxwLltA30068.jpg


原文链接:https://blog.51cto.com/liangxiao/1966795
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章