前言
看這篇文章的或多或少都是平時開發(fā)有涉及到圖片加載的,你可能是新手技術人員,也可能摸爬滾打多年的老司機,不管你是想知道怎么加載圖片,還是想?yún)⒖枷氯绾慰焖偌?,本文盡量都分享下自己的心得,如果能幫助到你的話,也算是自己的一份沉淀。話不多說,直接進入正文。
1.為什么講圖片加載的集成呢?
其實我們都知道,圖片的加載無非就是將圖片(圖片源可以有多種,如網(wǎng)絡圖片,本地圖片等)成功地顯示在我們的圖片容器上(如ImageView),本地資源圖片很簡單,可能直接setBackground就可以達到效果,但如果是網(wǎng)絡圖片呢,寫個線程將圖片下載下來?然后本地存儲下來?再加載出來?那么,是不是要涉及到下載,存儲甚至還要考慮緩存等問題,線程的維護等等一些繁瑣又容易出錯的問題,如果需要顯示圖片的地方非常多呢?
有沒有辦法可以幫我們省去做重復性的工作呢?答案當然是有,就是代碼的封裝,把核心的邏輯封裝成工具方便調(diào)用,也就是把圖片下載到存儲的過程封裝起來,甚至考慮將圖片的加載也包含進去,就不用每次都手動去將下載好的圖片設置到圖片容器上。
2.確定實現(xiàn)思路
對于新手或有鉆研精神的你,可以選擇自己造鍋踩坑,也可以跟隨絕大多數(shù)人的步伐,使用開源的圖片加載庫(這里向開源致敬),android的圖片加載庫有很多,如Gilde、Picasso,F(xiàn)resco等,經(jīng)歷了大眾的考驗,性能和穩(wěn)定性不用我們考慮,可以專心實現(xiàn)我們的業(yè)務。以下,我們拿Gilde作為我們的主要使用對象。
3.使用場景
業(yè)務的復雜往往要求圖片的使用場景不局限于將圖片加載出來就可以,有時候還需要諸如圓角(上下左右,或僅右上左下圓角,或不同方向圓角大小不一樣),模糊,加載縮略圖等等。上邊提到的開源圖片加載庫可以很好地幫我們實現(xiàn),具體的使用大家可以自行搜索使用教程,還是比較簡單明了的。
4.高級進階
這里是本文的重中之重,前面講的其實都是為了引出對圖片加載的思考。拿Gilde來說,看下我們加載一張圖片需要怎么做
Glide.with(context).load(imageUrl).dontAnimate().into(imageView);
是不是很簡單,Glide已經(jīng)為我們提供了方便的調(diào)用api,在我們的應用中需要加載圖片的時候into一下就可以了,接下來整個圖片的從下載到存儲到緩存到顯示,甚至顯示占位圖,都交給Glide處理就好了。
正在你高興的時候,哪一天設計出了新的圖片顯示效果,可能Gilde已滿足不了了,當然這里不是說Glide不行,至少在我用起來還是滿足現(xiàn)在的所有需求的,我只是說明了需求的多樣性需要我們的技術也跟上步伐,或者技術大佬出于各種原因,要求我們用另外一種圖片加載庫。
換就換唄。不,你可別。換當然可以換,但你想想,如果我們的應用很多地方都用了之前的Glide庫加載圖片,那豈不是換成其它的就要改很多地方,我們能忍受這種復制粘貼刪除這種累心的沒技術含量的工作?先不說其他,首先這種替換的做法是不優(yōu)雅的。
能不能有一種方法,能快速響應類似這種需求的變化,或者說如果下次又需要更換圖片加載庫的時候怎么辦。終于到我們本篇文章的主題了。以下我分享下個人的寫法
4.1 圖片加載工具類
/** * 作者:lpx on 2019/10/29 14:07 * Email : 1966353889@qq.com * Describe:圖片加載工具類(單例) */ public final class ImageLoader { /*由于instance = new Singleton(),這并非是一個原子操作,事實上在 JVM 中這句話大概做了下面 3 件事情。 1.給 instance 分配內(nèi)存 2.調(diào)用 Singleton 的構造函數(shù)來初始化成員變量 3.將instance對象指向分配的內(nèi)存空間(執(zhí)行完這步instance就為非null了) 但是在 JVM 的即時編譯器中存在指令重排序的優(yōu)化。也就是說上面的第二步和第三步的順序是不能保證的,最終的執(zhí)行順序可能是 1-2-3 也可能是 1-3-2。如果是后者,則在 3 執(zhí)行完畢、2 未執(zhí)行之前,被線程二搶占了,這時 instance 已經(jīng)是非 null 了(但卻沒有初始化),所以線程二會直接返回 instance,然后使用,然后順理成章地報錯。 我們只需要將 instance 變量聲明成 volatile 就可以了。*/ private static volatile ImageLoader mInstance; private BaseImageLoaderStrategy mStrategy; private ImageLoader() { /*初始化時設置圖片加載策略為Glide*/ setImageLoaderStrategy(new GlideImageLoaderStrategy()); } public static ImageLoader getInstance() { if (mInstance == null) { synchronized ) { if (mInstance == null) { mInstance = new ImageLoader(); } } } return mInstance; } /** * 設置圖片加載策略(根據(jù)使用的圖片加載框架實現(xiàn)對應的BaseImageLoaderStrategy并在這里設置) */ private void setImageLoaderStrategy(BaseImageLoaderStrategy strategy) { mStrategy = strategy; } /** * 加載圖片 * * @param context 上下文 * @param url 圖片地址(泛型) * @param view 圖片宿主 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <LoadAddress, V extends View> void load(Context context, LoadAddress url, V view, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, placeholder); } } /** * 加載圖片 * * @param context 上下文 * @param url 圖片地址 * @param view 圖片宿主 * @param listener 加載監(jiān)聽 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <LoadAddress, V extends View, L> void load(Context context, LoadAddress url, V view, ImageLoaderCallback<L> listener, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, listener, placeholder); } } /** * 加載圖片 * * @param context 上下文 * @param url 圖片地址 * @param view 圖片宿主 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <V extends View, LoadAddress> void circle(Context context, LoadAddress url, V view, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, placeholder); } } /** * 加載圖片 * * @param context 上下文 * @param url 圖片地址 * @param view 圖片宿主 * @param listener 加載監(jiān)聽 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <LoadAddress, V extends View, L> void circle(Context context, LoadAddress url, V view, ImageLoaderCallback<L> listener, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, listener, placeholder); } } /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片地址 * @param view 圖片宿主 * @param radius 圓角半徑 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <LoadAddress, V extends View> void round(Context context, LoadAddress url, V view, float radius, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, radius, placeholder); } } /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片地址 * @param view 圖片宿主 * @param radius 圓角半徑 * @param listener 加載監(jiān)聽 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <LoadAddress, V extends View, L> void round(Context context, LoadAddress url, V view, float radius, ImageLoaderCallback<L> listener, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, radius, listener, placeholder); } } /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片地址 * @param view 圖片宿主 * @param radius 左上角圓角半徑,右上角圓角半徑,左下角圓角半徑,右下角圓角半徑 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <LoadAddress, V extends View> void round(Context context, LoadAddress url, V view, float[] radius, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, radius, placeholder); } } /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片地址 * @param view 圖片宿主 * @param radius 左上角圓角半徑,右上角圓角半徑,左下角圓角半徑,右下角圓角半徑 * @param listener 加載監(jiān)聽 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ public <LoadAddress, V extends View, L> void round(Context context, LoadAddress url, V view, float[] radius, ImageLoaderCallback<L> listener, int... placeholder) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { mS(context, url, view, radius, listener, placeholder); } } public void clear(Context context, @NonNull View view) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { if (mStrategy instanceof GlideImageLoaderStrategy) { ((GlideImageLoaderStrategy) mStrategy).clear(context, view); } } } public void pauseRequests(Context context) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { if (mStrategy instanceof GlideImageLoaderStrategy) { ((GlideImageLoaderStrategy) mStrategy).pauseRequests(context); } } } public void pauseAllRequests(Context context) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { if (mStrategy instanceof GlideImageLoaderStrategy) { ((GlideImageLoaderStrategy) mStrategy).pauseAllRequests(context); } } } public void resumeRequests(Context context) { if (mStrategy == null) { throw new NullPointerException("you should invoke setImageLoaderStrategy first"); } else { if (mStrategy instanceof GlideImageLoaderStrategy) { ((GlideImageLoaderStrategy) mStrategy).resumeRequests(context); } } } }
4.2 圖片加載策略
/** * 作者:lpx on 2019/10/29 14:07 * Email : 1966353889@qq.com * Describe:圖片加載策略 */ public interface BaseImageLoaderStrategy<V extends View, L> { /** * 加載圖片 * * @param context 上下文 * @param url 圖片地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView */ <LoadAddress> void load(Context context, LoadAddress url, V view, int... placeholder); /** * 加載圖片 * * @param context 上下文 * @param url 圖片加載地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView * @param listener 加載監(jiān)聽 */ <LoadAddress> void load(Context context, LoadAddress url, V view, ImageLoaderCallback<L> listener, int... placeholder); /** * 加載圖片(圓形) * * @param context 上下文 * @param url 圖片加載地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView */ <LoadAddress> void circle(Context context, LoadAddress url, V view, int... placeholder); /** * 加載圖片(圓形) * * @param context 上下文 * @param url 圖片加載地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView * @param listener 加載監(jiān)聽 */ <LoadAddress> void circle(Context context, LoadAddress url, V view, ImageLoaderCallback<L> listener, int... placeholder); /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片加載地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView * @param radius 圓角半徑 */ <LoadAddress> void round(Context context, LoadAddress url, V view, float radius, int... placeholder); /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片加載地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView * @param radius 圓角半徑 * @param listener 加載監(jiān)聽 */ <LoadAddress> void round(Context context, LoadAddress url, V view, float radius, ImageLoaderCallback<L> listener, int... placeholder); /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片加載地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView * @param radius 左上角圓角半徑,右上角圓角半徑,左下角圓角半徑,右下角圓角半徑 * @param placeholder 占位圖(加載時或加載錯誤占位圖),可選參數(shù),第一個元素代表加載時占位圖,第二個元素代表加載錯誤占位圖 */ <LoadAddress> void round(Context context, LoadAddress url, V view, float[] radius, int... placeholder); /** * 加載圖片(圓角) * * @param context 上下文 * @param url 圖片加載地址 * @param view 不同的圖片加載框架要設置的視圖可能不一樣,如Glide為ImageView而Fresco則為SimpleDraweeView * @param radius 左上角圓角半徑,右上角圓角半徑,左下角圓角半徑,右下角圓角半徑 * @param listener 加載監(jiān)聽 */ <LoadAddress> void round(Context context, LoadAddress url, V view, float[] radius, ImageLoaderCallback<L> listener, int... placeholder); /** * 是否為支持的加載類型(不同圖片加載框架支持的加載類型可能不一樣,在具體的實現(xiàn)類中實現(xiàn)邏輯) */ <LoadAddress> boolean supportLoad(LoadAddress url); }
4.3 Glide圖片加載策略
/** * 作者:lpx on 2019/10/29 14:07 * Email : 1966353889@qq.com * Describe:Glide圖片加載策略 */ public class GlideImageLoaderStrategy implements BaseImageLoaderStrategy<ImageView, ImageResult> { @Override public <LoadAddress> void load(Context context, LoadAddress url, ImageView view, int... placeholder) { if (supportLoad(url)) { if (placeholder != null && > 0 && < 3) { RequestOptions options = new RequestOptions().placeholder(placeholder[0]); if ( == 2) o(placeholder[1]); Glide.with(context).load(url).apply(options).dontAnimate().into(view); } else { Glide.with(context).load(url).dontAnimate().into(view); } } } @Override public <LoadAddress> void load(Context context, LoadAddress url, ImageView view, final ImageLoaderCallback<ImageResult> listener, int... placeholder) { if (supportLoad(url)) { if (placeholder != null && > 0 && < 3) { RequestOptions options = new RequestOptions().placeholder(placeholder[0]); if ( == 2) o(placeholder[1]); Glide.with(context).load(url).apply(options).addListener(listener == null ? null : new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { li(); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { li(); return false; } }).dontAnimate().into(view); } else { Glide.with(context).load(url).addListener(listener == null ? null : new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { li(); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { li(); return false; } }).dontAnimate().into(view); } } } @Override public <LoadAddress> void circle(Context context, LoadAddress url, ImageView view, int... placeholder) { if (supportLoad(url)) { /*占位圖進行圓形處理*/ RequestBuilder<Drawable> load = null, error = null; if (placeholder != null && > 0 && < 3) { load = Glide.with(context) .load(placeholder[0]).dontAnimate() .apply()); if ( == 2) error = Glide.with(context) .load(placeholder[1]).dontAnimate() .apply()); } Glide.with(context).load(url).apply()).thumbnail(load).error(error).dontAnimate().into(view); } } @Override public <LoadAddress> void circle(Context context, LoadAddress url, ImageView view, final ImageLoaderCallback<ImageResult> listener, int... placeholder) { if (supportLoad(url)) { /*占位圖進行圓形處理*/ RequestBuilder<Drawable> load = null, error = null; if (placeholder != null && > 0 && < 3) { load = Glide.with(context) .load(placeholder[0]).dontAnimate() .apply()); if ( == 2) error = Glide.with(context) .load(placeholder[1]).dontAnimate() .apply()); } Glide.with(context).load(url).apply()).thumbnail(load).error(error).dontAnimate().addListener(listener == null ? null : new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { li(); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { li(); return false; } }).into(view); } } @Override public <LoadAddress> void round(Context context, LoadAddress url, ImageView view, float radius, int... placeholder) { if (supportLoad(url)) { /*占位圖進行圓角處理*/ RequestBuilder<Drawable> load = null, error = null; if (placeholder != null && > 0 && < 3) { load = Glide.with(context) .load(placeholder[0]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(radius, view.getScaleType()))); if ( == 2) error = Glide.with(context) .load(placeholder[1]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(radius, view.getScaleType()))); } RequestOptions options = new RequestOptions().transform(new GlideRoundTransform(radius, view.getScaleType())); Glide.with(context).load(url).apply(options).thumbnail(load).error(error).dontAnimate().into(view); } } @Override public <LoadAddress> void round(Context context, LoadAddress url, ImageView view, float radius, final ImageLoaderCallback<ImageResult> listener, int... placeholder) { if (supportLoad(url)) { /*占位圖進行圓角處理*/ RequestBuilder<Drawable> load = null, error = null; if (placeholder != null && > 0 && < 3) { load = Glide.with(context) .load(placeholder[0]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(radius, view.getScaleType()))); if ( == 2) error = Glide.with(context) .load(placeholder[1]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(radius, view.getScaleType()))); } RequestOptions options = new RequestOptions().transform(new GlideRoundTransform(radius, view.getScaleType())); Glide.with(context).load(url).apply(options).thumbnail(load).error(error).addListener(listener == null ? null : new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { li(); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { li(); return false; } }).dontAnimate().into(view); } } @Override public <LoadAddress> void round(Context context, LoadAddress url, ImageView view, float[] radius, int... placeholder) { if (supportLoad(url)) { float leftTop = 0, rightTop = 0, leftBottom = 0, rightBottom = 0; if (radius != null && radius.length == 4) { leftTop = radius[0]; rightTop = radius[1]; leftBottom = radius[2]; rightBottom = radius[3]; } /*占位圖進行圓角處理*/ RequestBuilder<Drawable> load = null, error = null; if (placeholder != null && > 0 && < 3) { load = Glide.with(context) .load(placeholder[0]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(leftTop, rightTop, leftBottom, rightBottom, view.getScaleType()))); if ( == 2) error = Glide.with(context) .load(placeholder[1]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(leftTop, rightTop, leftBottom, rightBottom, view.getScaleType()))); } RequestOptions options = new RequestOptions().transform(new GlideRoundTransform(leftTop, rightTop, leftBottom, rightBottom, view.getScaleType())); Glide.with(context).load(url).apply(options).thumbnail(load).error(error).dontAnimate().into(view); } } @Override public <LoadAddress> void round(Context context, LoadAddress url, ImageView view, float[] radius, final ImageLoaderCallback<ImageResult> listener, int... placeholder) { if (supportLoad(url)) { float leftTop = 0, rightTop = 0, leftBottom = 0, rightBottom = 0; if (radius != null && radius.length == 4) { leftTop = radius[0]; rightTop = radius[1]; leftBottom = radius[2]; rightBottom = radius[3]; } /*占位圖進行圓角處理*/ RequestBuilder<Drawable> load = null, error = null; if (placeholder != null && > 0 && < 3) { load = Glide.with(context) .load(placeholder[0]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(leftTop, rightTop, leftBottom, rightBottom, view.getScaleType()))); if ( == 2) error = Glide.with(context) .load(placeholder[1]).dontAnimate() .apply(new RequestOptions().transform(new GlideRoundTransform(leftTop, rightTop, leftBottom, rightBottom, view.getScaleType()))); } RequestOptions options = new RequestOptions().transform(new GlideRoundTransform(leftTop, rightTop, leftBottom, rightBottom, view.getScaleType())); Glide.with(context).load(url).apply(options).thumbnail(load).error(error).addListener(listener == null ? null : new RequestListener<Drawable>() { @Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) { li(); return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { li(); return false; } }).dontAnimate().into(view); } } @Override public <LoadAddress> boolean supportLoad(LoadAddress url) { return url instanceof Bitmap || url instanceof Drawable || url instanceof String || url instanceof Uri || url instanceof File || url instanceof Integer || url instanceof byte[]; } public void clear(Context context, @NonNull View view) { Glide.with(context).clear(view); } public void pauseRequests(Context context) { Glide.with(context).pauseRequests(); } public void pauseAllRequests(Context context) { Glide.with(context).pauseAllRequests(); } public void resumeRequests(Context context) { Glide.with(context).resumeRequests(); } }
4.4 Glide圓角transform(跟隨ImageView的scaleType縮放)
/** * 作者:lpx on 2019/10/29 14:07 * Email : 1966353889@qq.com * Describe:Glide圓角transform(跟隨ImageView的scaleType縮放) */ public class GlideRoundTransform extends BitmapTransformation { private ImageView.ScaleType scaleType; /** * 左上角,右上角,左下角,右下角四個方向圓角半徑 */ private float leftTop, rightTop, leftBottom, rightBottom; public GlideRoundTransform(float radius, ImageView.ScaleType scaleType) { leftTop = rightTop = leftBottom = rightBottom = radius; = scaleType; } public GlideRoundTransform(float leftTop, float rightTop, float leftBottom, float rightBottom, ImageView.ScaleType scaleType) { = leftTop; = rightTop; = leftBottom; = rightBottom; = scaleType; } public GlideRoundTransform(float leftTop, float rightTop, float leftBottom, float rightBottom) { = leftTop; = rightTop; = leftBottom; = rightBottom; } public GlideRoundTransform radius(float radius) { leftTop = rightTop = leftBottom = rightBottom = radius; return this; } public GlideRoundTransform scaleType scaleType) { = scaleType; return this; } /** * 左上角設置圓角 * * @param leftTop 是否在左上角設置圓角 */ public GlideRoundTransform leftTop(float leftTop) { = leftTop; return this; } /** * 右上角設置圓角 * * @param rightTop 是否在右上角設置圓角 */ public GlideRoundTransform rightTop(float rightTop) { = rightTop; return this; } /** * 左下角設置圓角 * * @param leftBottom 是否在左下角設置圓角 */ public GlideRoundTransform leftBottom(float leftBottom) { = leftBottom; return this; } /** * 右下角設置圓角 * * @param rightBottom 是否在右下角設置圓角 */ public GlideRoundTransform rightBottom(float rightBottom) { = rightBottom; return this; } public static GlideRoundTransform newBuilder() { return new GlideRoundTransform(10, ImageView.ScaleTy); } @Override protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) { if (scaleType != null) { switch (scaleType) { case CENTER_CROP: toTransform = Tran(pool, toTransform, outWidth, outHeight); break; case FIT_CENTER: toTransform = Tran(pool, toTransform, outWidth, outHeight); break; case CENTER_INSIDE: toTransform = Tran(pool, toTransform, outWidth, outHeight); break; } } return Tran(pool, toTransform, leftTop, rightTop, rightBottom, leftBottom); } @Override public void updateDiskCacheKey(@NonNull MessageDigest messageDigest) { } }
4.5 圖片加載回調(diào)
/** * 作者:lpx on 2019/10/29 14:07 * Email : 196635389@qq.com * Describe:圖片加載回調(diào) */ public interface ImageLoaderCallback<T> { void onSuccess(T... result); void onFailure(T... result); void onCancel(T... result); }
/** * 作者:lpx on 2019/10/29 10:50 * Email : 196635389@qq.com * Describe:用于圖片加載監(jiān)聽回調(diào)傳值(可根據(jù)圖片加載框架的加載回調(diào)的參數(shù)來設置此類具體包含的屬性和方法) */ public class ImageResult { }
4.6 使用
這樣,我們在需要加載圖片的地方調(diào)用ImageLoader就可以了,如
ImageLoader.getInstance().load(context,imageUrl,view);
ImageLoader也提供了多種加載圖片的方法,注釋都寫得很清楚,就不展開說明了。
4.6 更換圖片加載庫
如果我們需要更換圖片加載庫的時候只需要更改ImageLoader即可,即自定義繼承BaseImageLoaderStrategy的圖片實現(xiàn)策略類,重寫各種圖片加載的方法,然后在ImageLoader的構造方法調(diào)用setImageLoaderStrategy(BaseImageLoaderStrategy strategy)設置圖片加載策略就可以了。
自定義BaseImageLoaderStrategy可參考上邊的GlideImageLoaderStrategy。
結尾
是不是很方便快捷,希望本文可以幫助到您,也希望各位不吝賜教,提出您在使用中的寶貴意見,謝謝。
1.《安卓后端如何加載圖片 圖片加載不出來是前端問題還是后端問題》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡信息知識,僅代表作者本人觀點,與本網(wǎng)站無關,侵刪請聯(lián)系頁腳下方聯(lián)系方式。
2.《安卓后端如何加載圖片 圖片加載不出來是前端問題還是后端問題》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進行證實,對其原創(chuàng)性、真實性、完整性、及時性不作任何保證。
3.文章轉載時請保留本站內(nèi)容來源地址,http://f99ss.com/keji/3218715.html