使用Glide加載圖片系列之一從不同的數(shù)據(jù)源加載圖片

與其他圖片加載庫相同号俐,Glide除了可以加載網(wǎng)絡圖片之外,也可以加載本地圖片。甚至還可以從各種各樣奇葩的數(shù)據(jù)源中加載圖片捅伤。

加載網(wǎng)絡圖片

很多情況下,我們使用圖片加載庫就是為了加載網(wǎng)絡圖片巫玻。網(wǎng)絡操作是一個很復雜的東西丛忆。試想一下,如果沒有圖片加載庫仍秤,我們就要手動去下載圖片,緩存圖片熄诡,最后再從文件里面讀取bitmap并設(shè)置到Imageview里面。這還算好的诗力,要是在Listview里面你會更頭疼的凰浮。原因我就不說了,你懂的~~再加上各種各樣的Bitmap操作苇本,保準你再也不想擼代碼了袜茧。而且Bitmap這東西還很占內(nèi)存,伺候不好瓣窄,很容易就會引發(fā)OOM笛厦,app吧唧就閃退了!康栈!

圖片加載庫的優(yōu)勢就在于此递递。簡簡單單一句話喷橙,下載,緩存登舞,加載統(tǒng)統(tǒng)搞定贰逾。簡直就是美好一生的東西。而Glide就是這樣使人美好一生的東西之一菠秒。

說了這么多疙剑,Glide如何加載網(wǎng)絡圖片?很簡單践叠,就上次的三句話:

ImageView targetImageView = (ImageView) findViewById(R.id.imageView);
String internetUrl = "http://i.imgur.com/idojSYm.png";
Glide
    .with(context)
    .load(internetUrl)
    .into(targetImageView);

木有什么亂七八糟的東西言缤,直接傳入要加載圖片的url就可以了。那么圖片加載庫有很多禁灼,為什么選擇Glide呢管挟?很簡單,因為它流暢弄捕,不卡僻孝,尤其是在Listview中。嗯守谓,就是醬~

加載本地圖片

下表是.load()可以傳入的參數(shù)及說明

參數(shù) 說明
.load(String string) string可以為一個文件路徑穿铆、uri或者url
.load(Uri uri) uri類型
.load(File file) 文件
.load(Integer resourceId) 資源Id,R.drawable.xxx或者R.mipmap.xxx
.load(byte[] model) byte[]類型
.load(T model) 自定義類型

從上面可以看到Glide不僅可以加載網(wǎng)絡圖片,還可以加載本地圖片斋荞≤癯可接受的參數(shù)有文件路徑,uri平酿,文件凤优,資源id等◎诒耍基本上滿足了大部分的需求别洪。雖然加載本地圖片不像網(wǎng)絡圖片那樣復雜,但我還是建議使用Glide來加載本地圖片柳刮。因為它是內(nèi)存友好的,而且還會“偷偷地”幫我們做很多事情痒钝。比如內(nèi)存緩存秉颗,Bitmap復用,修正照片方向等送矩。當然為了滿足各種各樣的需求蚕甥,僅僅加載圖片是不夠的,你還需要對圖片進行各種各樣的變換栋荸,也就是Transformation菇怀。后面我們會詳細了解的凭舶。

加載自定義數(shù)據(jù)源

前面的表格中有一個是我們不熟悉的,就是.load(T model)爱沟,即自定義的數(shù)據(jù)源類型帅霜。那么如何去實現(xiàn)呢?

實際上呼伸,加載自定義數(shù)據(jù)源主要是通過ModelLoader接口來實現(xiàn)的身冀。由于沒有在實際項目中用到過,這方面的經(jīng)驗比較少括享。想深入了解的搂根,可以參考這篇文章

不過從官方Wiki上來看铃辖,設(shè)計ModelLoader接口的初衷用來加載不同尺寸的圖片的剩愧。眾所周知,Android設(shè)備屏幕分辨率千奇百怪娇斩,大到2K仁卷,小到320p。如果在低分辨率的手機上加載大圖成洗,不僅損耗用戶流量五督,而且很容易造成OOM;在高分辨的手機上瓶殃,加載小圖又會出現(xiàn)模糊的情況充包,用戶體驗極差。很多時候遥椿,為了省事基矮,很多app都會選擇一個中間分辨率,然后自適應大小冠场。當然這樣做無可厚非家浇,但是有更好的辦法,我們?yōu)槭裁床蝗L試呢碴裙?

那么如何使用Glide來實現(xiàn)這一具體需求呢钢悲?首先你要實現(xiàn)自己的ModelLoader,比較簡單的方法是繼承BaseGlideUrlLoader舔株。

public interface MyDataModel {
    public String buildUrl(int width, int height);
} 
public class MyUrlLoader extends BaseGlideUrlLoader<MyDataModel> {
    @Override
    protected String getUrl(MyDataModel model, int width, int height) {
        // Construct the url for the correct size here.
        return model.buildUrl(width, height);
    }
}

接下來我們可以這樣來加載圖片:

Glide.with(this)
     .using(new MyUrlLoader(this))
     .load(new MyDataModel() {
          @Override
          public String buidUrl(int width, int height) {
              if (width >= 600) {
                  return url1;
              } else {
                  return url2;
                }
          }
      })
     .into(imageView);

.using(new MyUrlLoader(this)):使用我們自己的ModeLoader;
.load(new MyDataModel()):加載我們自定義的數(shù)據(jù)源

這里需要解釋下getUrl的三個參數(shù):
model:你加載的數(shù)據(jù)源
width:你加載的圖片的寬度(px)
height:你加載的圖片的高度(px)

這樣莺琳,我們在高分率的設(shè)備上加載大圖的url1,在低分辨率的設(shè)備上加載小圖url2载慈。從而實現(xiàn)了根據(jù)不同手機上的像素值大小加載不同尺寸的圖片的需求惭等。

當然如果你不想每次都是用.using(new MyUrlLoader()),就需要實現(xiàn)一個自定義的ModelLoaderFactory并在GlideModule中注冊办铡。

public class MyGlideModule implements GlideModule {
    ...
    @Override
    public void registerComponents(Context context, Glide glide) {
        glide.register(MyDataModel.class, InputStream.class, 
            new MyUrlLoader.Factory());
    }
}

同時也要在AndroidManifest.xml聲明

<meta-data
    android:name="com.mypackage.MyGlideModule"
    android:value="GlideModule" />

如果你有多個自定義的GlideModule類辞做,那么也要在AndroidManifest.xml中聲明多個GlideModule琳要。

對于上面的加載不同尺寸的圖片,Google的2014年I/O大會App中有一篇文章專門用來介紹這個的秤茅,地址在這里稚补。大概原理是這樣子的:

在服務端有下面的幾個可以加載的url:

URL 圖片大小
myserver.com/images/__w-200-400-600-800-1000__/session1.jpg 原始尺寸
myserver.com/images/w200/session1.jpg 200px
myserver.com/images/w400/session1.jpg 400px
myserver.com/images/w600/session1.jpg 600px
myserver.com/images/w800/session1.jpg 800px
myserver.com/images/w1000/session1.jpg 1000px

那么客戶端如何根據(jù)不同的手機分辨率去加載不同的url呢?

Google是這樣做的嫂伞,下面是核心代碼:

//定義正則表達式
private static final Pattern PATTERN =
      Pattern.compile("__w-((?:-?\\d+)+)__");

@Override
protected String getUrl(String model, int width, int height) {
    Matcher m = PATTERN.matcher(model);
    int bestBucket = 0;
    if (m.find()) {
        String[] found = m.group(1).split("-");//拿到可以加載的尺寸數(shù)組
        for (String bucketStr : found) {
            bestBucket = Integer.parseInt(bucketStr);
            if (bestBucket >= width) {//剛好大于要加載的尺寸孔厉,直接跳出循環(huán)
                // the best bucket is the first immediately
                // bigger than the requested width
                break;
            }
        }
        if (bestBucket > 0) {//返回合適尺寸的url
            model = m.replaceFirst("w"+bestBucket);
        }
    }
    return model;
}

大概的步驟如下:
1.根據(jù)服務端可加載的圖片url定義正則表達式
2.根據(jù)正則匹配,獲取到可以加載的圖片尺寸數(shù)組
3.根據(jù)要加載的Imageview的大小帖努,選擇合適的尺寸的url
4.拼接url并返回

上面的例子中有200,400,600,800,1000是可以加載的撰豺,如果你要加載的Imageview的大小為600px,當遍歷數(shù)組到600時,就會直接跳出循環(huán)拼余,返回600px大小圖片的url污桦,Glide就會加載600px的圖片。

最后送上一個小demo:https://github.com/Alluretears/GldieDemo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匙监,一起剝皮案震驚了整個濱河市凡橱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亭姥,老刑警劉巖稼钩,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異达罗,居然都是意外死亡坝撑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門粮揉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巡李,“玉大人,你說我怎么就攤上這事扶认∏壤梗” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵辐宾,是天一觀的道長狱从。 經(jīng)常有香客問我,道長叠纹,這世上最難降的妖魔是什么矫夯? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮吊洼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘制肮。我一直安慰自己冒窍,他們只是感情好递沪,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著综液,像睡著了一般款慨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谬莹,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天檩奠,我揣著相機與錄音,去河邊找鬼附帽。 笑死埠戳,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蕉扮。 我是一名探鬼主播整胃,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喳钟!你這毒婦竟也來了屁使?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤奔则,失蹤者是張志新(化名)和其女友劉穎蛮寂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體易茬,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡酬蹋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了疾呻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片除嘹。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖岸蜗,靈堂內(nèi)的尸體忽然破棺而出尉咕,到底是詐尸還是另有隱情,我是刑警寧澤璃岳,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布年缎,位于F島的核電站,受9級特大地震影響铃慷,放射性物質(zhì)發(fā)生泄漏单芜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一犁柜、第九天 我趴在偏房一處隱蔽的房頂上張望洲鸠。 院中可真熱鬧,春花似錦、人聲如沸扒腕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘾腰。三九已至皆的,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蹋盆,已是汗流浹背费薄。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留栖雾,地道東北人楞抡。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像岩灭,于是被迫代替她去往敵國和親拌倍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容