前言:
輪播圖是一種常用的廣告控件,幾乎在每個App中都會出現。本文闡述一個之前在開發中遇到的問題,就是使用OkGo異步加載網絡圖片並分別設置給輪播圖;如果方法不好,樂於接受批評!
一:引入依賴
依賴有輪播圖插件<RollPageView>和OkGo;(我略懶,並沒有自己寫一個輪播圖)
compile 'com.jude:rollviewpager:1.4.6'//輪播圖 compile 'com.lzy.net:okgo:3.0.4' |
二:使用
佈局就不放出來了,文章主要寫後臺邏輯部分,首先輪播圖的創建依賴一個Adapter適配器,我們需要先構建這個適配器。我給他起名叫做AdaverLoadAdapter;
package com.rx.base.adapter; import android.graphics.Bitmap; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import com.jude.rollviewpager.RollPagerView; import com.jude.rollviewpager.adapter.LoopPagerAdapter; import java.util.ArrayList; import static android.content.ContentValues.TAG; /** * 廣告輪播圖適配器(傳入url) * Created by 賈恆飛 on 2017/12/27 0027. */ public class AdvertLoadAdapter extends LoopPagerAdapter { private ArrayList<String> imgs; private Load load; private Deploy deploy; public AdvertLoadAdapter(RollPagerView viewPager, ArrayList<String> imgs, Load load) { super(viewPager); this.imgs = imgs; this.load = load; } public AdvertLoadAdapter(RollPagerView viewPager, ArrayList<String> imgs, Deploy deploy) { super(viewPager); this.imgs = imgs; this.deploy = deploy; } @Override public View getView(ViewGroup container, int position) { ImageView view = new ImageView(container.getContext()); if (load != null){ view.setImageBitmap(load.loadBitmap(load.verifyUrl(imgs.get(position))));//設置每張圖片 } if (deploy != null){ deploy.deployBitmap(view,deploy.verifyUrl(imgs.get(position))); Log.d(TAG, "getView: ImageUrl::"+imgs.get(position)); } view.setScaleType(ImageView.ScaleType.CENTER_CROP); view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); return view; } @Override public int getRealCount() { return imgs.size(); } //圖片下載接口 public interface Load{ //判斷地址是否正確 String verifyUrl(String url); //網絡加載圖片 Bitmap loadBitmap(String url); } //圖片配置接口 public interface Deploy{ //判斷地址是否正確 String verifyUrl(String url); //網絡配置圖片 void deployBitmap(ImageView imageView,String url); } } |
適配器根據不同情況,提供了開啓下載通道或者直接設置圖片兩種方式。如果選擇開啓下載通道模式,適配器默認提供一個接口,接收返回的BitMap,內部設置給每個Image對象,然而事實證明這個方法是不科學的,因爲網絡加載的延時性,這種方法只存在與同步中有效;第二種方法是適配器提供的Deploy接口,接口返回所持有的每一個Image對象,並且返回當前Image對象所對應的url,在外部實現圖片的加載和設置;
因爲我的這個適配器是封裝在baseModel中的,Model中並沒有引入任何的網絡加載框架,所以把網絡加載部分放權給其他層做,本身只負責構建和顯示;
根據這個適配器,我在控制層進行了基本的設置,在model層進行了數據的請求;
控制層代碼:
控制層代碼少的可憐:@Override public void initRollViewPage(RollPagerView rollViewPage) { AdvertLoadAdapter adapter = new AdvertLoadAdapter(rollViewPage,mRocmmModel.gainRollUrl(),this); rollViewPage.setAdapter(adapter); } 在當前頁實現一個接口Deploy @Override public String verifyUrl(String url) { return url; } @Override public void deployBitmap(ImageView imageView, String url) { mRocmmModel.gainRollBitmap(url,imageView); }在這裏我們暫時不對url做任何處理,如果需要對資源url做加密操作是可以在這裏完成解密操作,把加密的字符串解析成正常的字符串然後傳遞給deployBitmap方法; |
@Override public void gainRollBitmap(String url, final ImageView imageView) { Api.net().gainBitMap(url, new BitmapCallback() { @Override public void onSuccess(Response<Bitmap> response) { imageView.setImageBitmap(response.body()); } }); }對於OkGo的請求部分,我把它在Api中進行了封裝,使得所有數據的存取操作都圍繞Api工具類進行,對於本地和網絡的區分在於取得是net對象還是dao對象,這樣model只關注與對數據的集中處理,Api則負責實際的數據請求和數據查詢; |
OkGo請求:
@Override public void gainBitMap(String url, BitmapCallback bitmapCallback) { OkGo.<Bitmap>post(url) .retryCount(ApiConfig.retryCount) .tag(url) .cacheTime(ApiConfig.cacheTime) .cacheMode(CacheMode.DEFAULT) .execute(bitmapCallback); } |