首页 文章 精选 留言 我的

精选列表

搜索[优化],共10000篇文章
优秀的个人博客,低调大师

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

相信大家看到上面的巨图会很懵逼~最近产品经理朝令夕改,有点烦,要不是还有外包项目在做,就不想干了,所以忍了,先做完十一后再说,毕竟找工作还是有点折腾,需要更高的薪水和技术的沉淀。好吧,啰嗦了一把,下面开始正题,最近一直在研究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); GlideOptionsglideOptions=newGlideOptions(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: packagecom.example.shining.p042_largep_w_picpath.glide37; importandroid.graphics.drawable.Drawable; importandroid.view.View; importcom.bumptech.glide.request.animation.GlideAnimation; importcom.bumptech.glide.request.target.ViewTarget; importcom.shizhefei.view.largep_w_picpath.ILargeImageView; importcom.shizhefei.view.largep_w_picpath.factory.FileBitmapDecoderFactory; importjava.io.File; /** *Abase{@linkcom.bumptech.glide.request.target.Target}fordisplayingresourcesin *{@linkandroid.widget.ImageView}s. * *@param<Z>Thetypeofresourcethatthistargetwilldisplayinthewrapped{@linkandroid.widget.ImageView}. */ publicclassLargeImageViewTargetextendsViewTarget<View,File>{ privateILargeImageViewlargeImageView; public<VextendsView&ILargeImageView>LargeImageViewTarget(Vview){ super(view); this.largeImageView=view; } /** *Setsthegiven{@linkandroid.graphics.drawable.Drawable}ontheviewusing *{@linkandroid.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}. * *@paramplaceholder{@inheritDoc} */ @Override publicvoidonLoadStarted(Drawableplaceholder){ largeImageView.setImageDrawable(placeholder); } /** *Setsthegiven{@linkandroid.graphics.drawable.Drawable}ontheviewusing *{@linkandroid.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}. * *@paramerrorDrawable{@inheritDoc} */ @Override publicvoidonLoadFailed(Exceptione,DrawableerrorDrawable){ largeImageView.setImageDrawable(errorDrawable); } @Override publicvoidonResourceReady(Fileresource,GlideAnimation<?superFile>glideAnimation){ largeImageView.setImage(newFileBitmapDecoderFactory(resource)); } /** *Setsthegiven{@linkandroid.graphics.drawable.Drawable}ontheviewusing *{@linkandroid.widget.ImageView#setImageDrawable(android.graphics.drawable.Drawable)}. * *@paramplaceholder{@inheritDoc} */ @Override publicvoidonLoadCleared(Drawableplaceholder){ largeImageView.setImageDrawable(placeholder); } } OkHttpProgressGlideModule: packagecom.example.shining.p042_largep_w_picpath.glide37; importandroid.content.Context; importandroid.os.Handler; importandroid.os.Looper; importcom.bumptech.glide.Glide; importcom.bumptech.glide.GlideBuilder; importcom.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; importcom.bumptech.glide.load.model.GlideUrl; importcom.bumptech.glide.module.GlideModule; importjava.io.IOException; importjava.io.InputStream; importjava.util.Map; importjava.util.concurrent.ConcurrentHashMap; importokhttp3.HttpUrl; importokhttp3.Interceptor; importokhttp3.MediaType; importokhttp3.OkHttpClient; importokhttp3.Request; importokhttp3.Response; importokhttp3.ResponseBody; importokio.Buffer; importokio.BufferedSource; importokio.ForwardingSource; importokio.Okio; importokio.Source; //TODOadd<meta-dataandroid:value="GlideModule"android:name="....OkHttpProgressGlideModule"/> //TODOadd<meta-dataandroid:value="GlideModule"tools:node="remove"android:name="com.bumptech.glide.integration.okhttp.OkHttpGlideModule"/> //ornotuse'okhttp@aar'inGradledepdendencies publicclassOkHttpProgressGlideModuleimplementsGlideModule{ @Override publicvoidapplyOptions(Contextcontext,GlideBuilderbuilder){ } @Override publicvoidregisterComponents(Contextcontext,Glideglide){ OkHttpClient.Builderbuilder=newOkHttpClient.Builder(); builder.networkInterceptors().add(createInterceptor(newDispatchingProgressListener())); glide.register(GlideUrl.class,InputStream.class,newOkHttpUrlLoader.Factory(builder.build())); } privatestaticInterceptorcreateInterceptor(finalResponseProgressListenerlistener){ returnnewInterceptor(){ @Override publicResponseintercept(Chainchain)throwsIOException{ Requestrequest=chain.request(); Responseresponse=chain.proceed(request); returnresponse.newBuilder() .body(newOkHttpProgre***esponseBody(request.url(),response.body(),listener)) .build(); } }; } publicinterfaceUIProgressListener{ voidonProgress(longbytesRead,longexpectedLength); /** *Controlhowoftenthelistenerneedsanupdate.0%and100%willalwaysbedispatched. * *@returninpercentage(0.2=call{@link#onProgress}aroundevery0.2percentofprogress) */ floatgetGranualityPercentage(); } publicstaticvoidforget(Stringurl){ DispatchingProgressListener.forget(url); } publicstaticvoidexpect(Stringurl,UIProgressListenerlistener){ DispatchingProgressListener.expect(url,listener); } privateinterfaceResponseProgressListener{ voidupdate(HttpUrlurl,longbytesRead,longcontentLength); } privatestaticclassDispatchingProgressListenerimplementsResponseProgressListener{ privatestaticfinalMap<String,UIProgressListener>LISTENERS=newConcurrentHashMap<>(); privatestaticfinalMap<String,Long>PROGRESSES=newConcurrentHashMap<>(); privatefinalHandlerhandler; DispatchingProgressListener(){ this.handler=newHandler(Looper.getMainLooper()); } staticvoidforget(Stringurl){ LISTENERS.remove(url); PROGRESSES.remove(url); } staticvoidexpect(Stringurl,UIProgressListenerlistener){ LISTENERS.put(url,listener); } @Override publicvoidupdate(HttpUrlurl,finallongbytesRead,finallongcontentLength){ //System.out.printf("%s:%d/%d=%.2f%%%n",url,bytesRead,contentLength,(100f*bytesRead)/contentLength); Stringkey=url.toString(); finalUIProgressListenerlistener=LISTENERS.get(key); if(listener==null){ return; } //长度是错误的移除监听 if(contentLength<=bytesRead){ forget(key); } if(needsDispatch(key,bytesRead,contentLength,listener.getGranualityPercentage())){ handler.post(newRunnable(){ @Override publicvoidrun(){ listener.onProgress(bytesRead,contentLength); } }); } } privatebooleanneedsDispatch(Stringkey,longcurrent,longtotal,floatgranularity){ if(granularity==0||current==0||total==current){ returntrue; } floatpercent=100f*current/total; longcurrentProgress=(long)(percent/granularity); LonglastProgress=PROGRESSES.get(key); if(lastProgress==null||currentProgress!=lastProgress){ PROGRESSES.put(key,currentProgress); returntrue; }else{ returnfalse; } } } privatestaticclassOkHttpProgre***esponseBodyextendsResponseBody{ privatefinalHttpUrlurl; privatefinalResponseBodyresponseBody; privatefinalResponseProgressListenerprogressListener; privateBufferedSourcebufferedSource; OkHttpProgre***esponseBody(HttpUrlurl,ResponseBodyresponseBody, ResponseProgressListenerprogressListener){ this.url=url; this.responseBody=responseBody; this.progressListener=progressListener; } @Override publicMediaTypecontentType(){ returnresponseBody.contentType(); } @Override publiclongcontentLength(){ returnresponseBody.contentLength(); } @Override publicBufferedSourcesource(){ if(bufferedSource==null){ bufferedSource=Okio.buffer(source(responseBody.source())); } returnbufferedSource; } privateSourcesource(Sourcesource){ returnnewForwardingSource(source){ longtotalBytesRead=0L; @Override publiclongread(Buffersink,longbyteCount)throwsIOException{ longbytesRead=super.read(sink,byteCount); longfullLength=responseBody.contentLength(); if(bytesRead==-1){//thissourceisexhausted totalBytesRead=fullLength; }else{ totalBytesRead+=bytesRead; } progressListener.update(url,totalBytesRead,fullLength); returnbytesRead; } }; } } } 这里需要注意一下,需要延迟配置GlideModule, xml: <!--Glide与OkHttp3集成--> <meta-data android:name="com.example.lagerp_w_picpath_test.glide.OkHttpProgressGlideModule" android:value="GlideModule"/> onCreate: finalGlideglide=Glide.get(this); OkHttpProgressGlideModulea=newOkHttpProgressGlideModule(); a.registerComponents(this,glide); 这里这样写的原因是在你加载图片的时候给加载的进度过程,自定义OkHttpProgressGlideModule, ProgressTarget: packagecom.example.shining.p042_largep_w_picpath.glide37; importandroid.graphics.drawable.Drawable; importcom.bumptech.glide.Glide; importcom.bumptech.glide.request.animation.GlideAnimation; importcom.bumptech.glide.request.target.Target; publicabstractclassProgressTarget<T,Z>extendsWrappingTarget<Z>implementsOkHttpProgressGlideModule.UIProgressListener{ privateTmodel; privatebooleanignoreProgress=true; publicProgressTarget(Tmodel,Target<Z>target){ super(target); this.model=model; } publicfinalTgetModel(){ returnmodel; } publicfinalvoidsetModel(Tmodel){ Glide.clear(this);//indirectlycallscleanup this.model=model; } /** *ConvertamodelintoanUrlstringthatisusedtomatchuptheOkHttprequests.Forexplicit *{@linkcom.bumptech.glide.load.model.GlideUrlGlideUrl}loadsthisneedstoreturn *{@linkcom.bumptech.glide.load.model.GlideUrl#toStringUrltoStringUrl}.Forcustommodelsdothesameasyour *{@linkcom.bumptech.glide.load.model.stream.BaseGlideUrlLoaderBaseGlideUrlLoader}does. * *@parammodelreturntherepresentationofthegivenmodel,DONOTuse{@link#getModel()}insidethismethod. *@returnastableUrlrepresentationofthemodel,otherwisetheprogressreportingwon'twork */ protectedStringtoUrlString(Tmodel){ returnString.valueOf(model); } @Override publicfloatgetGranualityPercentage(){ return1.0f; } privatevoidstart(){ OkHttpProgressGlideModule.expect(toUrlString(model),this); ignoreProgress=false; } privatevoidcleanup(){ ignoreProgress=true; Tmodel=this.model;//saveincaseitgetsmodified OkHttpProgressGlideModule.forget(toUrlString(model)); this.model=null; } @Override publicvoidonLoadStarted(Drawableplaceholder){ super.onLoadStarted(placeholder); start(); } @Override publicvoidonResourceReady(Zresource,GlideAnimation<?superZ>animation){ cleanup(); super.onResourceReady(resource,animation); } @Override publicvoidonLoadFailed(Exceptione,DrawableerrorDrawable){ cleanup(); super.onLoadFailed(e,errorDrawable); } @Override publicvoidonLoadCleared(Drawableplaceholder){ cleanup(); super.onLoadCleared(placeholder); } } WrappingTarget: packagecom.example.shining.p042_largep_w_picpath.glide37; importandroid.graphics.drawable.Drawable; importcom.bumptech.glide.request.Request; importcom.bumptech.glide.request.animation.GlideAnimation; importcom.bumptech.glide.request.target.SizeReadyCallback; importcom.bumptech.glide.request.target.Target; publicclassWrappingTarget<Z>implementsTarget<Z>{ protectedfinalTarget<Z>target; publicWrappingTarget(Target<Z>target){ this.target=target; } @Override publicvoidgetSize(SizeReadyCallbackcb){ if(target!=null) target.getSize(cb); } @Override publicvoidonLoadStarted(Drawableplaceholder){ if(target!=null) target.onLoadStarted(placeholder); } @Override publicvoidonLoadFailed(Exceptione,DrawableerrorDrawable){ if(target!=null) target.onLoadFailed(e,errorDrawable); } @Override publicvoidonResourceReady(Zresource,GlideAnimation<?superZ>glideAnimation){ if(target!=null) target.onResourceReady(resource,glideAnimation); } @Override publicvoidonLoadCleared(Drawableplaceholder){ if(target!=null)target.onLoadCleared(placeholder); } privateRequestrequest; @Override publicRequestgetRequest(){ returnrequest; } @Override publicvoidsetRequest(Requestrequest){ this.request=request; if(target!=null) target.setRequest(request); } @Override publicvoidonStart(){ if(target!=null) target.onStart(); } @Override publicvoidonStop(){ if(target!=null) target.onStop(); } @Override publicvoidonDestroy(){ 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: packagecom.example.shining.p042_largep_w_picpath.activity; importandroid.graphics.Bitmap; importandroid.graphics.BitmapFactory; importandroid.graphics.drawable.Drawable; importandroid.os.Bundle; importandroid.support.v7.app.AppCompatActivity; importandroid.view.View; importcom.bumptech.glide.Glide; importcom.bumptech.glide.request.animation.GlideAnimation; importcom.bumptech.glide.request.target.SizeReadyCallback; importcom.bumptech.glide.request.target.Target; importcom.example.shining.p042_largep_w_picpath.R; importcom.example.shining.p042_largep_w_picpath.glide37.OkHttpProgressGlideModule; importcom.example.shining.p042_largep_w_picpath.glide37.ProgressTarget; importcom.shizhefei.view.largep_w_picpath.LargeImageView; importcom.shizhefei.view.largep_w_picpath.factory.FileBitmapDecoderFactory; importjava.io.File; importjava.io.IOException; importjava.io.InputStream; importjava.net.HttpURLConnection; importjava.net.MalformedURLException; importjava.net.URL; importio.netopen.hotbitmapgg.library.view.RingProgressBar; publicclassMainActivityLargeImageGlideextendsAppCompatActivity{ privateLargeImageViewlargeImageView; privateRingProgressBarringProgressBar; @Override protectedvoidonCreate(BundlesavedInstanceState){ 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); //Stringurl="http://short.im.rockhippo.cn/uploads/msg/201703/20170309/1485/1489068660846.jpg"; //URLfileUrl=null; //Filefile=null; //try{ //fileUrl=newURL(url); //file=newFile(fileUrl.toURI()); //}catch(MalformedURLException|URISyntaxExceptione){ //e.printStackTrace(); //} // //assertfile!=null; //largeImageView.setImage(newFileBitmapDecoderFactory(file)); //Stringurl="https://s2.51cto.com/wyfs02/M02/06/F4/wKiom1nA9iSRwF1BADe7ZVL2w4Q127.jpg"; //Stringurl="https://s2.51cto.com/wyfs02/M00/06/F4/wKiom1nA-Aiy9qMkAAR3_qzZ1is031.jpg"; Stringurl="https://s3.51cto.com/wyfs02/M00/A5/A5/wKioL1nA-WrQ8NSkAADpAlDnsrM054.jpg"; finalGlideglide=Glide.get(this); OkHttpProgressGlideModulea=newOkHttpProgressGlideModule(); a.registerComponents(this,glide); newThread(){ @Override publicvoidrun(){ super.run(); Glide.get(getApplicationContext()).clearDiskCache(); runOnUiThread(newRunnable(){ @Override publicvoidrun(){ //Toast.makeText(getApplicationContext(),"清除缓存成功",Toast.LENGTH_SHORT).show(); } }); } }.start(); Glide.with(this).load(url).downloadOnly(newProgressTarget<String,File>(url,null){ @Override publicvoidonLoadStarted(Drawableplaceholder){ super.onLoadStarted(placeholder); ringProgressBar.setVisibility(View.VISIBLE); ringProgressBar.setProgress(0); } @Override publicvoidonProgress(longbytesRead,longexpectedLength){ intp=0; if(expectedLength>=0){ p=(int)(100*bytesRead/expectedLength); } ringProgressBar.setProgress(p); } @Override publicvoidonResourceReady(Fileresource,GlideAnimation<?superFile>animation){ super.onResourceReady(resource,animation); ringProgressBar.setVisibility(View.GONE); //largeImageView.setEnabled(false); largeImageView.setImage(newFileBitmapDecoderFactory(resource)); } @Override publicvoidgetSize(SizeReadyCallbackcb){ cb.onSizeReady(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL); } }); } /** *根据图片的url路径获得Bitmap对象 * *@paramurl *@return */ privateBitmapreturnBitmap(Stringurl){ URLfileUrl=null; Bitmapbitmap=null; try{ fileUrl=newURL(url); }catch(MalformedURLExceptione){ e.printStackTrace(); } try{ HttpURLConnectionconn=(HttpURLConnection)fileUrl.openConnection(); conn.setDoInput(true); conn.connect(); InputStreamis=conn.getInputStream(); bitmap=BitmapFactory.decodeStream(is); is.close(); }catch(IOExceptione){ e.printStackTrace(); } returnbitmap; } } 加载本地assets文件夹大图,这里要说一下,经过测试,手机取drawable里面的巨图会OOM,平板不会,但是assets目录手机和平板都支持,因为drawable取的是路径加载,assets是文件流,所以不会OOM, 加载drawable目录MainActivityLargeImageLocal1: packagecom.example.shining.p042_largep_w_picpath.activity; importandroid.os.Bundle; importandroid.support.v7.app.AppCompatActivity; importcom.example.shining.p042_largep_w_picpath.R; importcom.shizhefei.view.largep_w_picpath.LargeImageView; publicclassMainActivityLargeImageLocal1extendsAppCompatActivity{ privateLargeImageViewlocalDemo_photoView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_largep_w_picpath_local); localDemo_photoView=(LargeImageView)findViewById(R.id.localDemo_photoView); StringfileName=getIntent().getStringExtra("file_name"); localDemo_photoView.setImage(getResources().getDrawable(R.drawable.qm3)); runOnUiThread(newRunnable(){ @Override publicvoidrun(){ localDemo_photoView.setScale(0.5f); } }); } } 加载assets目录MainActivityLargeImageLocal2: packagecom.example.shining.p042_largep_w_picpath.activity; importandroid.os.Bundle; importandroid.support.v7.app.AppCompatActivity; importcom.example.shining.p042_largep_w_picpath.R; importcom.shizhefei.view.largep_w_picpath.BlockImageLoader; importcom.shizhefei.view.largep_w_picpath.LargeImageView; importcom.shizhefei.view.largep_w_picpath.factory.InputStreamBitmapDecoderFactory; importjava.io.IOException; importjava.io.InputStream; publicclassMainActivityLargeImageLocal2extendsAppCompatActivity{ privateLargeImageViewlargeImageView; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_largep_w_picpath_local); largeImageView=(LargeImageView)findViewById(R.id.localDemo_photoView); try{ StringfileName=getIntent().getStringExtra("file_name"); //通过文件的方式加载sd卡中的大图 //localDemo_photoView.setImage(newFileBitmapDecoderFactory(file)); //通过流的方式加载assets文件夹里面的大图 InputStreaminputStream=getAssets().open("qm.jpg"); largeImageView.setImage(newInputStreamBitmapDecoderFactory(inputStream)); //localDemo_photoView.setImage(newInputStreamBitmapDecoderFactory(inputStream),getResources().getDrawable(R.drawable.mvc)); runOnUiThread(newRunnable(){ @Override publicvoidrun(){ largeImageView.setScale(0.5f); largeImageView.setOnImageLoadListener(newBlockImageLoader.OnImageLoadListener(){ @Override publicvoidonBlockImageLoadFinished(){ } @Override publicvoidonLoadImageSize(intp_w_picpathWidth,intp_w_picpathHeight){ Stringa=p_w_picpathHeight+""; } @Override publicvoidonLoadFail(Exceptione){ } }); //largeImageView.setCriticalScaleValueHook(newLargeImageView.CriticalScaleValueHook(){ //@Override //publicfloatgetMinScale(LargeImageViewlargeImageView,intp_w_picpathWidth,intp_w_picpathHeight,floatsuggestMinScale){ //return15; //} // //@Override //publicfloatgetMaxScale(LargeImageViewlargeImageView,intp_w_picpathWidth,intp_w_picpathHeight,floatsuggestMaxScale){ //return30; //} //}); } }); }catch(IOExceptione){ e.printStackTrace(); } } } 这里给你提供一下小细节,大部分人在后台返回色值或者UI设计0%透明度的时候烦恼,给大家记录一下透明的计算方法: <colorname="transparent_white">#00ffffff</color> 00这两位的计算:255*50%(透明度UI会告诉你)=结果128转化成16进制就是80这两位你需要的。 colorUtil: <?xmlversion="1.0"encoding="utf-8"?> <resources> <colorname="colorPrimary">#3F51B5</color> <colorname="colorPrimaryDark">#303F9F</color> <colorname="colorAccent">#FF4081</color> <colorname="gray_line">#dfdfdf</color> <colorname="white">#ffffff</color> <!--白色--> <colorname="ivory">#fffff0</color> <!--象牙色--> <colorname="lightyellow">#ffffe0</color> <!--亮×××--> <colorname="yellow">#ffff00</color> <!--×××--> <colorname="snow">#fffafa</color> <!--雪白色--> <colorname="floralwhite">#fffaf0</color> <!--花白色--> <colorname="lemonchiffon">#fffacd</color> <!--柠檬绸色--> <colorname="cornsilk">#fff8dc</color> <!--米绸色--> <colorname="seaShell">#fff5ee</color> <!--海贝色--> <colorname="lavenderblush">#fff0f5</color> <!--淡紫红--> <colorname="papayawhip">#ffefd5</color> <!--番木色--> <colorname="blanchedalmond">#ffebcd</color> <!--白杏色--> <colorname="mistyrose">#ffe4e1</color> <!--浅玫瑰色--> <colorname="bisque">#ffe4c4</color> <!--桔×××--> <colorname="moccasin">#ffe4b5</color> <!--鹿皮色--> <colorname="navajowhite">#ffdead</color> <!--纳瓦白--> <colorname="peachpuff">#ffdab9</color> <!--桃色--> <colorname="gold">#ffd700</color> <!--金色--> <colorname="pink">#ffc0cb</color> <!--粉红色--> <colorname="lightpink">#ffb6c1</color> <!--亮粉红色--> <colorname="orange">#ffa500</color> <!--橙色--> <colorname="lightsalmon">#ffa07a</color> <!--亮肉色--> <colorname="darkorange">#ff8c00</color> <!--暗桔×××--> <colorname="coral">#ff7f50</color> <!--珊瑚色--> <colorname="hotpink">#ff69b4</color> <!--热粉红色--> <colorname="tomato">#ff6347</color> <!--西红柿色--> <colorname="orangered">#ff4500</color> <!--红橙色--> <colorname="deeppink">#ff1493</color> <!--深粉红色--> <colorname="fuchsia">#ff00ff</color> <!--紫红色--> <colorname="magenta">#ff00ff</color> <!--红紫色--> <colorname="red">#ff0000</color> <!--红色--> <colorname="oldlace">#fdf5e6</color> <!--老花色--> <colorname="lightgoldenrodyellow">#fafad2</color> <!--亮金×××--> <colorname="linen">#faf0e6</color> <!--亚麻色--> <colorname="antiquewhite">#faebd7</color> <!--古董白--> <colorname="salmon">#fa8072</color> <!--鲜肉色--> <colorname="ghostwhite">#f8f8ff</color> <!--幽灵白--> <colorname="mintcream">#f5fffa</color> <!--薄荷色--> <colorname="whitesmoke">#f5f5f5</color> <!--烟白色--> <colorname="beige">#f5f5dc</color> <!--米色--> <colorname="wheat">#f5deb3</color> <!--浅×××--> <colorname="sandybrown">#f4a460</color> <!--沙褐色--> <colorname="azure">#f0ffff</color> <!--天蓝色--> <colorname="honeydew">#f0fff0</color> <!--蜜色--> <colorname="aliceblue">#f0f8ff</color> <!--艾利斯兰--> <colorname="khaki">#f0e68c</color> <!--黄褐色--> <colorname="lightcoral">#f08080</color> <!--亮珊瑚色--> <colorname="palegoldenrod">#eee8aa</color> <!--苍麒麟色--> <colorname="violet">#ee82ee</color> <!--紫罗兰色--> <colorname="darksalmon">#e9967a</color> <!--暗肉色--> <colorname="lavender">#e6e6fa</color> <!--淡紫色--> <colorname="lightcyan">#e0ffff</color> <!--亮青色--> <colorname="burlywood">#deb887</color> <!--实木色--> <colorname="plum">#dda0dd</color> <!--洋李色--> <colorname="gainsboro">#dcdcdc</color> <!--淡灰色--> <colorname="crimson">#dc143c</color> <!--暗深红色--> <colorname="palevioletred">#db7093</color> <!--苍紫罗兰色--> <colorname="goldenrod">#daa520</color> <!--金麒麟色--> <colorname="orchid">#da70d6</color> <!--淡紫色--> <colorname="thistle">#d8bfd8</color> <!--蓟色--> <colorname="lightgray">#d3d3d3</color> <!--亮灰色--> <colorname="lightgrey">#d3d3d3</color> <!--亮灰色--> <colorname="tan">#d2b48c</color> <!--茶色--> <colorname="chocolate">#d2691e</color> <!--巧可力色--> <colorname="peru">#cd853f</color> <!--秘鲁色--> <colorname="indianred">#cd5c5c</color> <!--印第安红--> <colorname="mediumvioletred">#c71585</color> <!--中紫罗兰色--> <colorname="silver">#c0c0c0</color> <!--银色--> <colorname="darkkhaki">#bdb76b</color> <!--暗黄褐色--> <colorname="rosybrown">#bc8f8f</color> <!--褐玫瑰红--> <colorname="mediumorchid">#ba55d3</color> <!--中粉紫色--> <colorname="darkgoldenrod">#b8860b</color> <!--暗金×××--> <colorname="firebrick">#b22222</color> <!--火砖色--> <colorname="powderblue">#b0e0e6</color> <!--粉蓝色--> <colorname="lightsteelblue">#b0c4de</color> <!--亮钢兰色--> <colorname="paleturquoise">#afeeee</color> <!--苍宝石绿--> <colorname="greenyellow">#adff2f</color> <!--黄绿色--> <colorname="lightblue">#add8e6</color> <!--亮蓝色--> <colorname="darkgray">#a9a9a9</color> <!--暗灰色--> <colorname="darkgrey">#a9a9a9</color> <!--暗灰色--> <colorname="brown">#a52a2a</color> <!--褐色--> <colorname="sienna">#a0522d</color> <!--赭色--> <colorname="darkorchid">#9932cc</color> <!--暗紫色--> <colorname="palegreen">#98fb98</color> <!--苍绿色--> <colorname="darkviolet">#9400d3</color> <!--暗紫罗兰色--> <colorname="mediumpurple">#9370db</color> <!--中紫色--> <colorname="lightgreen">#90ee90</color> <!--亮绿色--> <colorname="darkseagreen">#8fbc8f</color> <!--暗海兰色--> <colorname="saddlebrown">#8b4513</color> <!--重褐色--> <colorname="darkmagenta">#8b008b</color> <!--暗洋红--> <colorname="darkred">#8b0000</color> <!--暗红色--> <colorname="blueviolet">#8a2be2</color> <!--紫罗兰蓝色--> <colorname="lightskyblue">#87cefa</color> <!--亮天蓝色--> <colorname="skyblue">#87ceeb</color> <!--天蓝色--> <colorname="gray">#808080</color> <!--灰色--> <colorname="grey">#808080</color> <!--灰色--> <colorname="olive">#808000</color> <!--橄榄色--> <colorname="purple">#800080</color> <!--紫色--> <colorname="maroon">#800000</color> <!--粟色--> <colorname="aquamarine">#7fffd4</color> <!--碧绿色--> <colorname="chartreuse">#7fff00</color> <!--黄绿色--> <colorname="lawngreen">#7cfc00</color> <!--草绿色--> <colorname="mediumslateblue">#7b68ee</color> <!--中暗蓝色--> <colorname="lightslategray">#778899</color> <!--亮蓝灰--> <colorname="lightslategrey">#778899</color> <!--亮蓝灰--> <colorname="slategray">#708090</color> <!--灰石色--> <colorname="slategrey">#708090</color> <!--灰石色--> <colorname="olivedrab">#6b8e23</color> <!--深绿褐色--> <colorname="slateblue">#6a5acd</color> <!--石蓝色--> <colorname="dimgray">#696969</color> <!--暗灰色--> <colorname="dimgrey">#696969</color> <!--暗灰色--> <colorname="mediumaquamarine">#66cdaa</color> <!--中绿色--> <colorname="cornflowerblue">#6495ed</color> <!--菊兰色--> <colorname="cadetblue">#5f9ea0</color> <!--军兰色--> <colorname="darkolivegreen">#556b2f</color> <!--暗橄榄绿--> <colorname="indigo">#4b0082</color> <!--靛青色--> <colorname="mediumturquoise">#48d1cc</color> <!--中绿宝石--> <colorname="darkslateblue">#483d8b</color> <!--暗灰蓝色--> <colorname="steelblue">#4682b4</color> <!--钢兰色--> <colorname="royalblue">#4169e1</color> <!--×××蓝--> <colorname="turquoise">#40e0d0</color> <!--青绿色--> <colorname="mediumseagreen">#3cb371</color> <!--中海蓝--> <colorname="limegreen">#32cd32</color> <!--橙绿色--> <colorname="darkslategray">#2f4f4f</color> <!--暗瓦灰色--> <colorname="darkslategrey">#2f4f4f</color> <!--暗瓦灰色--> <colorname="seagreen">#2e8b57</color> <!--海绿色--> <colorname="forestgreen">#228b22</color> <!--森林绿--> <colorname="lightseagreen">#20b2aa</color> <!--亮海蓝色--> <colorname="dodgerblue">#1e90ff</color> <!--闪兰色--> <colorname="midnightblue">#191970</color> <!--中灰兰色--> <colorname="aqua">#00ffff</color> <!--浅绿色--> <colorname="cyan">#00ffff</color> <!--青色--> <colorname="springgreen">#00ff7f</color> <!--春绿色--> <colorname="lime">#00ff00</color> <!--酸橙色--> <colorname="mediumspringgreen">#00fa9a</color> <!--中春绿色--> <colorname="darkturquoise">#00ced1</color> <!--暗宝石绿--> <colorname="deepskyblue">#00bfff</color> <!--深天蓝色--> <colorname="darkcyan">#008b8b</color> <!--暗青色--> <colorname="teal">#008080</color> <!--水鸭色--> <colorname="green">#008000</color> <!--绿色--> <colorname="darkgreen">#006400</color> <!--暗绿色--> <colorname="blue">#0000ff</color> <!--蓝色--> <colorname="mediumblue">#0000cd</color> <!--中兰色--> <colorname="darkblue">#00008b</color> <!--暗蓝色--> <colorname="navy">#000080</color> <!--海军色--> <colorname="black">#000000</color> <!--黑色--> <colorname="transparent">#0000</color> <!--透明--> <colorname="transparent2">#8000</color> <!--透明--> <colorname="style_red">#ff4c41</color> <colorname="style_divider_color">#C9C7CD</color> <!--common--> <colorname="c0">#ff000000</color> <colorname="c1">#D9000000</color> <colorname="c2">#8C000000</color> <colorname="c3">#66000000</color> <colorname="c4">#1A000000</color> <colorname="c5">#C34A42</color> <colorname="c6">#FF9800</color> <colorname="c7">#009734</color> <colorname="c8">#46AE36</color> <colorname="c9">#47B000</color> <colorname="c10">#007AFF</color> <colorname="c11">#1194F6</color> <colorname="c12">#9D1BB2</color> <colorname="transparent">#00000000</color> <colorname="transparent05">#0B000000</color> <colorname="transparent10">#1A000000</color> <colorname="transparent20">#33000000</color> <colorname="transparent30">#4D000000</color> <colorname="transparent40">#66000000</color> <colorname="transparent50">#80000000</color> <colorname="transparent60">#9A000000</color> <colorname="transparent70">#B3000000</color> <colorname="transparent80">#CC000000</color> <colorname="transparent90">#E5000000</color> <colorname="transparent100">#FF000000</color> <colorname="transparent_white">#00ffffff</color> <colorname="transparent10_white">#1Affffff</color> <colorname="transparent20_white">#33ffffff</color> <colorname="transparent30_white">#4Dffffff</color> <colorname="transparent40_white">#66ffffff</color> <colorname="transparent50_white">#80ffffff</color> <colorname="transparent60_white">#9Affffff</color> <colorname="transparent70_white">#B3ffffff</color> <colorname="transparent80_white">#CCffffff</color> <colorname="transparent90_white">#E5ffffff</color> <colorname="transparent100_white">#FFffffff</color> <colorname="placeholder_color">#1A000000</color> <colorname="white">#FFFFFF</color><!--白色--> <colorname="yellow">#fbc02d</color><!--×××--> <colorname="gold">#FFD700</color><!--金色--> <colorname="orange">#f57c00</color><!--橙色--> <colorname="red">#d01716</color><!--红色--> <colorname="gray">#808080</color><!--灰色--> <colorname="green">#0a7e07</color><!--绿色--> <colorname="blue">#455ede</color><!--蓝色--> <colorname="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' compileproject(':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) packagecom.example.shining.p041_glide411.glidedemo411.p_w_picpath; importandroid.os.Bundle; importandroid.support.annotation.Nullable; importandroid.support.v4.app.ActivityCompat; importandroid.support.v7.app.AppCompatActivity; importandroid.text.TextUtils; importandroid.util.Log; importandroid.view.View; importandroid.widget.Toast; importcom.bumptech.glide.Glide; importcom.bumptech.glide.load.engine.DiskCacheStrategy; importcom.bumptech.glide.load.engine.GlideException; importcom.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; importcom.bumptech.glide.request.RequestOptions; importcom.example.shining.glide411library.progress.CircleProgressView; importcom.example.shining.glide411library.progress.OnGlideImageViewListener; importcom.example.shining.glide411library.view.GlideImageLoader; importcom.example.shining.glide411library.view.GlideImageView; importcom.example.shining.p041_glide411.R; importjava.util.Random; publicclassSingleImageActivityextendsAppCompatActivity{ GlideImageViewglideImageView; CircleProgressViewprogressView; CircleProgressViewprogressView1; CircleProgressViewprogressView2; CircleProgressViewprogressView3; ViewmaskView; publicstaticfinalStringKEY_IMAGE_URL="p_w_picpath_url"; publicstaticfinalStringKEY_IMAGE_URL_THUMBNAIL="p_w_picpath_url_thumbnail"; Stringp_w_picpath_url; Stringp_w_picpath_url_thumbnail; @Override protectedvoidonCreate(@NullableBundlesavedInstanceState){ 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(); } privatevoidinitProgressView(){ //MainActivityGlide.isLoadAgain=newRandom().nextInt(3)==1; intrandomNum=newRandom().nextInt(3); switch(randomNum){ case1: progressView=progressView2; break; case2: progressView=progressView3; break; case0: default: progressView=progressView1; break; } progressView1.setVisibility(View.GONE); progressView2.setVisibility(View.GONE); progressView3.setVisibility(View.GONE); progressView.setVisibility(View.VISIBLE); } privatevoidloadImage(){ glideImageView.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewv){ ActivityCompat.finishAfterTransition(SingleImageActivity.this); } }); RequestOptionsrequestOptions=glideImageView.requestOptions(R.color.black) .centerCrop(); RequestOptionsrequestOptionsWithoutCache=glideImageView.requestOptions(R.color.black) .centerCrop() .skipMemoryCache(true) .diskCacheStrategy(DiskCacheStrategy.NONE); GlideImageLoaderp_w_picpathLoader=glideImageView.getImageLoader(); p_w_picpathLoader.setOnGlideImageViewListener(p_w_picpath_url,newOnGlideImageViewListener(){ @Override publicvoidonProgress(intpercent,booleanisDone,GlideExceptionexception){ 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) packagecom.example.shining.p041_glide411.glidedemo411; importandroid.content.Intent; importandroid.os.Bundle; importandroid.support.v4.app.ActivityCompat; importandroid.support.v4.app.ActivityOptionsCompat; importandroid.support.v7.app.AppCompatActivity; importandroid.text.TextUtils; importandroid.util.Log; importandroid.view.View; importandroid.widget.Toast; importcom.bumptech.glide.load.engine.DiskCacheStrategy; importcom.bumptech.glide.load.engine.GlideException; importcom.bumptech.glide.load.resource.drawable.DrawableTransitionOptions; importcom.bumptech.glide.request.RequestOptions; importcom.example.shining.glide411library.progress.CircleProgressView; importcom.example.shining.glide411library.progress.OnGlideImageViewListener; importcom.example.shining.glide411library.progress.OnProgressListener; importcom.example.shining.glide411library.view.GlideImageLoader; importcom.example.shining.glide411library.view.GlideImageView; importcom.example.shining.glide411library.view.ShapeImageView; importcom.example.shining.p041_glide411.R; importcom.example.shining.p041_glide411.glidedemo411.p_w_picpath.SingleImageActivity; importjava.util.Random; importstaticcom.example.shining.p041_glide411.glidedemo411.p_w_picpath.SingleImageActivity.KEY_IMAGE_URL; importstaticcom.example.shining.p041_glide411.glidedemo411.p_w_picpath.SingleImageActivity.KEY_IMAGE_URL_THUMBNAIL; publicclassMainActivityGlideextendsAppCompatActivity{ privateGlideImageViewp_w_picpath11; privateGlideImageViewp_w_picpath12; privateGlideImageViewp_w_picpath13; privateGlideImageViewp_w_picpath14; privateStringurl1="https://s3.51cto.com/wyfs02/M01/89/BA/wKioL1ga-u7QnnVnAAAfrCiGnBQ946_middle.jpg"; privateGlideImageViewp_w_picpath21; privateGlideImageViewp_w_picpath22; privateGlideImageViewp_w_picpath23; privateGlideImageViewp_w_picpath24; privateGlideImageViewp_w_picpath31; privateGlideImageViewp_w_picpath32; privateGlideImageViewp_w_picpath33; privateGlideImageViewp_w_picpath34; privateStringgif1="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"; privateGlideImageViewp_w_picpath41; privateCircleProgressViewprogressView1; privateStringp_w_picpath41BigUrl="https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1232.png"; privateStringp_w_picpath41SmallUrl="https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1231.png"; privateGlideImageViewp_w_picpath42; privateCircleProgressViewprogressView2; privateStringp_w_picpath42BigUrl="https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1234.png"; privateStringp_w_picpath42SmallUrl="https://raw.githubusercontent.com/geeklx/MyApplication/master/p040_glide4.0/screenshot/1233.png"; publicstaticbooleanisLoadAgain=false;//Justforfunwhenloadingp_w_picpaths! @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main_glide411); //Glide findview(); isLoadAgain=newRandom().nextInt(3)==1; line1(); line2(); line3(); line41(); line42(); } privatevoidfindview(){ 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); } privatevoidline41(){ p_w_picpath41.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewview){ Intentintent=newIntent(MainActivityGlide.this,SingleImageActivity.class); intent.putExtra(KEY_IMAGE_URL,p_w_picpath41BigUrl); intent.putExtra(KEY_IMAGE_URL_THUMBNAIL,p_w_picpath41SmallUrl); ActivityOptionsCompatcompat=ActivityOptionsCompat .makeSceneTransitionAnimation(MainActivityGlide.this,p_w_picpath41,getString(R.string.transitional_p_w_picpath)); ActivityCompat.startActivity(MainActivityGlide.this,intent,compat.toBundle()); } }); RequestOptionsrequestOptions=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(newOnGlideImageViewListener(){ @Override publicvoidonProgress(intpercent,booleanisDone,GlideExceptionexception){ 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); } }); } privatevoidline42(){ p_w_picpath42.setOnClickListener(newView.OnClickListener(){ @Override publicvoidonClick(Viewview){ Intentintent=newIntent(MainActivityGlide.this,SingleImageActivity.class); intent.putExtra(KEY_IMAGE_URL,p_w_picpath42BigUrl); intent.putExtra(KEY_IMAGE_URL_THUMBNAIL,p_w_picpath42BigUrl); ActivityOptionsCompatcompat=ActivityOptionsCompat .makeSceneTransitionAnimation(MainActivityGlide.this,p_w_picpath42,getString(R.string.transitional_p_w_picpath)); ActivityCompat.startActivity(MainActivityGlide.this,intent,compat.toBundle()); } }); RequestOptionsrequestOptions=p_w_picpath42.requestOptions(R.color.placeholder_color).centerCrop(); if(isLoadAgain){ requestOptions.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true); } //第二种方式加载:可以解锁更多功能 GlideImageLoaderp_w_picpathLoader=p_w_picpath42.getImageLoader(); p_w_picpathLoader.setOnGlideImageViewListener(p_w_picpath42SmallUrl,newOnGlideImageViewListener(){ @Override publicvoidonProgress(intpercent,booleanisDone,GlideExceptionexception){ 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); } privatevoidline3(){ p_w_picpath31.loadLocalImage(R.drawable.gif_robot_walk,R.drawable.ic_def_loading); p_w_picpath32.loadCircleImage(gif1,R.mipmap.ic_launcher).listener(newOnGlideImageViewListener(){ @Override publicvoidonProgress(intpercent,booleanisDone,GlideExceptionexception){ 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); } privatevoidline2(){ 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); } privatevoidline1(){ p_w_picpath11.loadImage(url1,R.color.black).listener(newOnProgressListener(){ @Override publicvoidonProgress(Stringp_w_picpathUrl,longbytesRead,longtotalBytes,booleanisDone,GlideExceptionexception){ 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(newView.OnClickListener(){ @Override publicvoidonClick(Viewview){ 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: packagecom.example.shining.p041_glide411.largep_w_picpath.glide411; importandroid.graphics.drawable.Drawable; importandroid.view.View; importcom.bumptech.glide.request.transition.Transition; importcom.bumptech.glide.request.target.ViewTarget; importcom.shizhefei.view.largep_w_picpath.ILargeImageView; importcom.shizhefei.view.largep_w_picpath.factory.FileBitmapDecoderFactory; importjava.io.File; /** *Abase{@linkcom.bumptech.glide.request.target.Target}fordisplayingresourcesin *{@linkandroid.widget.ImageView}s. * *@param<Z>Thetypeofresourcethatthistargetwilldisplayinthewrapped{@linkandroid.widget.ImageView}. */ publicclassLargeImageViewTargetextendsViewTarget<View,File>{ privateILargeImageViewlargeImageView; public<VextendsView&ILargeImageView>LargeImageViewTarget(Vview){ super(view); this.largeImageView=view; } /** *Setsthegiven{@linkDrawable}ontheviewusing *{@linkandroid.widget.ImageView#setImageDrawable(Drawable)}. * *@paramplaceholder{@inheritDoc} */ @Override publicvoidonLoadStarted(Drawableplaceholder){ largeImageView.setImageDrawable(placeholder); } /** *Setsthegiven{@linkDrawable}ontheviewusing *{@linkandroid.widget.ImageView#setImageDrawable(Drawable)}. * *@paramerrorDrawable{@inheritDoc} */ @Override publicvoidonLoadFailed(DrawableerrorDrawable){ largeImageView.setImageDrawable(errorDrawable); } @Override publicvoidonResourceReady(Fileresource,Transition<?superFile>glideAnimation){ largeImageView.setImage(newFileBitmapDecoderFactory(resource)); } /** *Setsthegiven{@linkDrawable}ontheviewusing *{@linkandroid.widget.ImageView#setImageDrawable(Drawable)}. * *@paramplaceholder{@inheritDoc} */ @Override publicvoidonLoadCleared(Drawableplaceholder){ largeImageView.setImageDrawable(placeholder); } } OkHttpProgressGlideModule: packagecom.example.shining.p041_glide411.largep_w_picpath.glide411; importandroid.content.Context; importandroid.os.Handler; importandroid.os.Looper; importcom.bumptech.glide.Glide; importcom.bumptech.glide.GlideBuilder; importcom.bumptech.glide.Registry; importcom.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; importcom.bumptech.glide.load.model.GlideUrl; importcom.bumptech.glide.module.AppGlideModule; importjava.io.IOException; importjava.io.InputStream; importjava.util.Map; importjava.util.concurrent.ConcurrentHashMap; importokhttp3.HttpUrl; importokhttp3.Interceptor; importokhttp3.MediaType; importokhttp3.OkHttpClient; importokhttp3.Request; importokhttp3.Response; importokhttp3.ResponseBody; importokio.Buffer; importokio.BufferedSource; importokio.ForwardingSource; importokio.Okio; importokio.Source; //TODOadd<meta-dataandroid:value="GlideModule"android:name="....OkHttpProgressGlideModule"/> //TODOadd<meta-dataandroid:value="GlideModule"tools:node="remove"android:name="com.bumptech.glide.integration.okhttp.OkHttpGlideModule"/> //ornotuse'okhttp@aar'inGradledepdendencies publicclassOkHttpProgressGlideModuleextendsAppGlideModule{ @Override publicvoidapplyOptions(Contextcontext,GlideBuilderbuilder){ } @Override publicvoidregisterComponents(Contextcontext,Glideglide,Registryregistry){ super.registerComponents(context,glide,registry); OkHttpClient.Builderbuilder=newOkHttpClient.Builder(); builder.networkInterceptors().add(createInterceptor(newDispatchingProgressListener())); glide.getRegistry().append(GlideUrl.class,InputStream.class,newOkHttpUrlLoader.Factory(builder.build())); //glide.register(GlideUrl.class,InputStream.class,newOkHttpUrlLoader.Factory(builder.build())); } privatestaticInterceptorcreateInterceptor(finalResponseProgressListenerlistener){ returnnewInterceptor(){ @Override publicResponseintercept(Chainchain)throwsIOException{ Requestrequest=chain.request(); Responseresponse=chain.proceed(request); returnresponse.newBuilder() .body(newOkHttpProgre***esponseBody(request.url(),response.body(),listener)) .build(); } }; } publicinterfaceUIProgressListener{ voidonProgress(longbytesRead,longexpectedLength); /** *Controlhowoftenthelistenerneedsanupdate.0%and100%willalwaysbedispatched. * *@returninpercentage(0.2=call{@link#onProgress}aroundevery0.2percentofprogress) */ floatgetGranualityPercentage(); } publicstaticvoidforget(Stringurl){ DispatchingProgressListener.forget(url); } publicstaticvoidexpect(Stringurl,UIProgressListenerlistener){ DispatchingProgressListener.expect(url,listener); } privateinterfaceResponseProgressListener{ voidupdate(HttpUrlurl,longbytesRead,longcontentLength); } privatestaticclassDispatchingProgressListenerimplementsResponseProgressListener{ privatestaticfinalMap<String,UIProgressListener>LISTENERS=newConcurrentHashMap<>(); privatestaticfinalMap<String,Long>PROGRESSES=newConcurrentHashMap<>(); privatefinalHandlerhandler; DispatchingProgressListener(){ this.handler=newHandler(Looper.getMainLooper()); } staticvoidforget(Stringurl){ LISTENERS.remove(url); PROGRESSES.remove(url); } staticvoidexpect(Stringurl,UIProgressListenerlistener){ LISTENERS.put(url,listener); } @Override publicvoidupdate(HttpUrlurl,finallongbytesRead,finallongcontentLength){ //System.out.printf("%s:%d/%d=%.2f%%%n",url,bytesRead,contentLength,(100f*bytesRead)/contentLength); Stringkey=url.toString(); finalUIProgressListenerlistener=LISTENERS.get(key); if(listener==null){ return; } //长度是错误的移除监听 if(contentLength<=bytesRead){ forget(key); } if(needsDispatch(key,bytesRead,contentLength,listener.getGranualityPercentage())){ handler.post(newRunnable(){ @Override publicvoidrun(){ listener.onProgress(bytesRead,contentLength); } }); } } privatebooleanneedsDispatch(Stringkey,longcurrent,longtotal,floatgranularity){ if(granularity==0||current==0||total==current){ returntrue; } floatpercent=100f*current/total; longcurrentProgress=(long)(percent/granularity); LonglastProgress=PROGRESSES.get(key); if(lastProgress==null||currentProgress!=lastProgress){ PROGRESSES.put(key,currentProgress); returntrue; }else{ returnfalse; } } } privatestaticclassOkHttpProgre***esponseBodyextendsResponseBody{ privatefinalHttpUrlurl; privatefinalResponseBodyresponseBody; privatefinalResponseProgressListenerprogressListener; privateBufferedSourcebufferedSource; OkHttpProgre***esponseBody(HttpUrlurl,ResponseBodyresponseBody, ResponseProgressListenerprogressListener){ this.url=url; this.responseBody=responseBody; this.progressListener=progressListener; } @Override publicMediaTypecontentType(){ returnresponseBody.contentType(); } @Override publiclongcontentLength(){ returnresponseBody.contentLength(); } @Override publicBufferedSourcesource(){ if(bufferedSource==null){ bufferedSource=Okio.buffer(source(responseBody.source())); } returnbufferedSource; } privateSourcesource(Sourcesource){ returnnewForwardingSource(source){ longtotalBytesRead=0L; @Override publiclongread(Buffersink,longbyteCount)throwsIOException{ longbytesRead=super.read(sink,byteCount); longfullLength=responseBody.contentLength(); if(bytesRead==-1){//thissourceisexhausted totalBytesRead=fullLength; }else{ totalBytesRead+=bytesRead; } progressListener.update(url,totalBytesRead,fullLength); returnbytesRead; } }; } } } ProgressTarget: packagecom.example.shining.p041_glide411.largep_w_picpath.glide411; importandroid.graphics.drawable.Drawable; importcom.bumptech.glide.Glide; importcom.bumptech.glide.request.target.Target; importcom.bumptech.glide.request.transition.Transition; importcom.example.shining.p041_glide411.application.DemoApplication; publicabstractclassProgressTarget<T,Z>extendsWrappingTarget<Z>implementsOkHttpProgressGlideModule.UIProgressListener{ privateTmodel; privatebooleanignoreProgress=true; publicProgressTarget(Tmodel,Target<Z>target){ super(target); this.model=model; } publicfinalTgetModel(){ returnmodel; } publicfinalvoidsetModel(Tmodel){ //Glide.clear(this);//indirectlycallscleanup Glide.with(DemoApplication.mContext).clear(this); this.model=model; } /** *ConvertamodelintoanUrlstringthatisusedtomatchuptheOkHttprequests.Forexplicit *{@linkcom.bumptech.glide.load.model.GlideUrlGlideUrl}loadsthisneedstoreturn *{@linkcom.bumptech.glide.load.model.GlideUrl#toStringUrltoStringUrl}.Forcustommodelsdothesameasyour *{@linkcom.bumptech.glide.load.model.stream.BaseGlideUrlLoaderBaseGlideUrlLoader}does. * *@parammodelreturntherepresentationofthegivenmodel,DONOTuse{@link#getModel()}insidethismethod. *@returnastableUrlrepresentationofthemodel,otherwisetheprogressreportingwon'twork */ protectedStringtoUrlString(Tmodel){ returnString.valueOf(model); } @Override publicfloatgetGranualityPercentage(){ return1.0f; } privatevoidstart(){ OkHttpProgressGlideModule.expect(toUrlString(model),this); ignoreProgress=false; } privatevoidcleanup(){ ignoreProgress=true; Tmodel=this.model;//saveincaseitgetsmodified OkHttpProgressGlideModule.forget(toUrlString(model)); this.model=null; } @Override publicvoidonLoadStarted(Drawableplaceholder){ super.onLoadStarted(placeholder); start(); } @Override publicvoidonResourceReady(Zresource,Transition<?superZ>animation){ cleanup(); super.onResourceReady(resource,animation); } @Override publicvoidonLoadFailed(DrawableerrorDrawable){ cleanup(); super.onLoadFailed(errorDrawable); } @Override publicvoidonLoadCleared(Drawableplaceholder){ cleanup(); super.onLoadCleared(placeholder); } } WrappingTarget: packagecom.example.shining.p041_glide411.largep_w_picpath.glide411; importandroid.graphics.drawable.Drawable; importandroid.support.annotation.Nullable; importcom.bumptech.glide.request.Request; importcom.bumptech.glide.request.target.SizeReadyCallback; importcom.bumptech.glide.request.target.Target; importcom.bumptech.glide.request.transition.Transition; publicclassWrappingTarget<Z>implementsTarget<Z>{ protectedfinalTarget<Z>target; publicWrappingTarget(Target<Z>target){ this.target=target; } @Override publicvoidgetSize(SizeReadyCallbackcb){ if(target!=null) target.getSize(cb); } @Override publicvoidremoveCallback(SizeReadyCallbackcb){ } @Override publicvoidonLoadStarted(Drawableplaceholder){ if(target!=null) target.onLoadStarted(placeholder); } @Override publicvoidonLoadFailed(@NullableDrawableerrorDrawable){ if(target!=null) target.onLoadFailed(errorDrawable); } @Override publicvoidonResourceReady(Zresource,Transition<?superZ>glideAnimation){ if(target!=null) target.onResourceReady(resource,glideAnimation); } @Override publicvoidonLoadCleared(Drawableplaceholder){ if(target!=null)target.onLoadCleared(placeholder); } privateRequestrequest; @Override publicRequestgetRequest(){ returnrequest; } @Override publicvoidsetRequest(Requestrequest){ this.request=request; if(target!=null) target.setRequest(request); } @Override publicvoidonStart(){ if(target!=null) target.onStart(); } @Override publicvoidonStop(){ if(target!=null) target.onStop(); } @Override publicvoidonDestroy(){ if(target!=null)target.onDestroy(); } } 权限别忘了: <uses-permissionandroid:name="android.permission.INTERNET"/> <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> 效果如下图: 图1: 图2: 图3: 图4: 今天介绍了很多东西,希望能帮到你~谢谢~ 附: 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

资源下载

更多资源
Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册