圖檔選擇器是android開發中會經常用到的一個功能,特别對于社交類的應用,比如頭像設定,比如發圖檔。自然imagepicker的輪子很多,今天介紹一個功能強大的輪子simagepicker
介紹
首先功能強大之處
首先基本的圖檔讀取顯示,以及圖檔更新監控
超大圖檔預覽,比如一張19m,10000*5000px的圖檔
圖檔的裁剪功能
豐富的可配置項,支援拍照選取,選取張數定義,支援選擇的圖檔過濾,
支援多種圖檔加載器(fresco,glide等)
廢話不說,先看效果
第一張頭像模式,第二張選擇多張圖檔(包括動畫和順暢的跳轉),第三張是分片加載超大圖(19.5m,10000*5000px)
頭像模式,支援裁剪
多選圖檔,流暢的頁面跳轉
超大圖預覽,可以看到漸變加載
如何使用
1.首先初始化(推薦在application的oncreate中調用)
simagepicker.init(new pickerconfig.builder().setappcontext(this)
.setimageloader(new frescoimageloader())
.settoolbasecolor(getcolor(r.color.colorprimary))
.build());
2.在需要選擇圖檔的地方調用
simagepicker
.from(mainactivity.this)
.maxcount(9)
.rowcount(3)
.pickmode(simagepicker.mode_image)
.fileinterceptor(new singlefilelimitinterceptor())
.forresult(request_code_image);
可配置項
1.全局配置(即初始化時傳入的pickerconfig,此配置作用于simagepicker整個使用過程)
配置參數
參數含義
setimageloader(imageloader)
使用的圖檔加載器。demo工程中實作了fresco和glide兩種imageloader,可以參考
settoolbarcolor(int)
picker的主色調,預設值是app的primarycolor
setappcontext(context)
picker内部用到的context,傳入applicationcontext即可
2.單次配置(即每次調用simagepicker時傳入的參數,此參數隻對這次調用生效)
from(activity or fragment)
調用圖檔選擇器可從activity或者fragment進入,最後的結果會在onactivityresult()傳回,現在傳回的結果有兩個值,使用者選擇的圖檔的路徑清單data.getstringarraylistextra(photopickeractivity.extra_result_selection);使用者是否選擇了原圖data.getbooleanextra(photopickeractivity.extra_result_original, false);
maxcount(int)
此次選擇允許的最大選擇數量,預設是1.比如發朋友圈最多選擇9張圖就傳9
rowcount(int)
圖檔清單單排展示多少張圖
setselected(list)
預設已經被選中的圖檔
pickmode(int)
選圖的模式,現在有頭像模式和普通模式兩種,頭像模式選中圖檔後預設會跳到圖檔裁剪頁面且預設隻能選擇一張
cropfilepath(string)
頭像模式下裁剪圖檔存放位址
showcamera(boolen)
是否要展示拍照入口
picktext(int)
picker裡右下角展示的文字資訊(比如配置選擇,發送,完成)
fileinterceptor(filechooseinterceptor)
圖檔過濾器,比如使用者選擇的單張圖檔大小有限制,即可寫在這個攔截器中,當使用者選擇過大圖檔時可以提示并且過濾
forresult(int requestcode)
打開圖檔選擇器,并且傳入requestcode
擷取結果
在調用圖檔選擇器的fragment或者activity中
@override
protected void onactivityresult(int requestcode, int resultcode, intent data) {
super.onactivityresult(requestcode, resultcode, data);
if (resultcode == activity.result_ok && requestcode == request_code_image) {
final arraylist<string> pathlist =
data.getstringarraylistextra(photopickeractivity.extra_result_selection);
final boolean original =
data.getbooleanextra(photopickeractivity.extra_result_original, false);
}
}
實作
圖檔資料庫讀取cursorloader
android3.0中引入了加載器/裝載器(loader)的功能,主要用于異步的方式加載資料庫。裝載器loader的特點:
裝載器提供異步資料加載的能力
裝載器監視資料資源并且當内容改變時發送新的結果;
在配置改變後重建的時候,裝載器自動的重連最後的裝載器遊标,是以,不需要重新查詢資料。
此項目也是使用loader去加載和監控圖檔資料,對于photo和album即圖檔和相冊分别有一個loader和一個controller,loader主要用于加載對應的資料,controller主要用于資料讀取到後的重新整理已經loader的釋放。
源碼中的對應
photoloader初始化
public static cursorloader newinstance(context context, album album, long minsize) {
if (album == null || album.isall()) {
return new photoloader(context, mediastore.images.media.external_content_uri, projection,
selection_size, new string[] {minsize + ""}, order_by);
return new photoloader(context, mediastore.images.media.external_content_uri, projection,
mediastore.images.media.bucket_id + " = ? and (" + selection_size + ")", new string[] {
album.getid(), minsize + ""}, order_by);
}
超大圖檔加載
對于超大的圖檔如何展示,這個是個比較棘手的問題
比如這張圖
<a href="http://7xpb9x.com1.z0.glb.clouddn.com/2017/01/20/b578e4755a32ac56a9c4b9a1f7e2822d.jpg">http://7xpb9x.com1.z0.glb.clouddn.com/2017/01/20/b578e4755a32ac56a9c4b9a1f7e2822d.jpg</a>
10000*5000的像素,接近20m。
這種圖檔肯定無法一次全部load到記憶體中,可以稍微計算一下即使是rgb_565的方式全部load進記憶體也要占用幾乎90m的記憶體,顯然是不太可能。可以回頭看一下第三張demo gif,顯然使用者打開一張圖時,在預設情況下,并不要求能看到細節,當使用者點選某區域放大時此時才會需要這一塊的清晰圖。那麼如何展示這種超大圖的思路基本基本就是
首先拿到檔案路徑,讀取出圖檔的寬高,并且根據螢幕和圖檔寬高計算出一個展示全圖的情況下的samplesize,根據這個值去加載出一個全景的圖
對圖檔進行分塊,分塊會分出不同放大倍數下(即選擇不同samplesize)下的一個塊清單,比如放大2倍時,放大4倍時對應怎麼分塊
當使用者點選放大某一區域時,根據放大的倍數以及目前的中心點選擇對應的塊進行load和渲染
在simagepicker項目中主要是用了subsamplingimageview
并且根據picker的需求做了些修改,來實作超大圖的預覽
圖檔清單展示
展示
由于使用了cursorloader,對于listview的話有cursoradapter可以使用,但是對于recyclerview确沒有對應的adapter,是以在源碼中可以看到實作了一個recyclecursoradapter,用于實作從cursor擷取資料已經自動重新整理。
相容
為了能夠相容多個圖檔加載器,simagepicker抽象了一個imageloader接口用于讓使用者自定義對應的圖檔加載器。
使用建議
simagepicker提供了jitpack上的依賴庫,可以很快的接入業務中,但是由于大部分的app對于imagepicker的使用都有各種業務需求,且simagepicker隻是抽象出了比較通用的一些配置,用于讓使用者能快速內建,是以此處還是建議使用者盡可能源碼引用的方式的使用simagepicker,既友善做一些調試,也可以很快的了解實作原理,說起來這種ui元件代碼應該是很好讀的,因為本身并不複雜。
作者:聶俊鴻
來源:51cto