在開始正文之前并徘,先欣賞一下這個圖片選擇器的效果
Matisse
一、基本使用
1扰魂、導入相應的依賴庫
Gradle? ?implementation'com.github.bumptech.glide:glide:4.6.1'
? ? ? ? ? ? ? ?implementation'com.zhihu.android:matisse:0.5.2-beta3'
有一點要注意一下麦乞, 這個圖片選擇庫是使用 Glide 或 Picasso 作為圖片加載引擎
如果你使用 Glide 作為你的圖片加載引擎,請?zhí)砑?Glide 的 README 上所說的規(guī)則劝评,以及添加額外的規(guī)則:
-dontwarncom.squareup.picasso.**
如果你使用 Picasso 作為你的圖片加載引擎姐直,請?zhí)砑?Picasso 的 README 上所說的規(guī)則,以及添加額外的規(guī)則:
-dontwarncom.bumptech.glide.**
2蒋畜、啟動 Matisse
在正式寫代碼之前简肴,有兩個相關的權限需要先申請:
android.permission.READ_EXTERNAL_STORAGEandroid.permission.WRITE_EXTERNAL_STORAGE
所以,如果你的 APP 是跑在 Android 6.0+ 的話百侧,你需要在下個步驟之前處理一下運行時權限砰识。
public class GifSizeFilterextends Filter {
private int mMinWidth;
? ? private int mMinHeight;
? ? private int mMaxSize;
? ? public GifSizeFilter(int minWidth, int minHeight, int maxSizeInBytes) {
? ? ? ? mMinWidth = minWidth;
? ? ? ? mMinHeight = minHeight;
? ? ? ? mMaxSize = maxSizeInBytes;
? ? }
@Override
? ? public SetconstraintTypes() {
????????????return new HashSet() {{
????????????????????add(MimeType.GIF);
? ? ? ? }};
? ? }
@SuppressLint("StringFormatInvalid")
@Override
? ? public IncapableCausefilter(Context context, Item item) {
????????if (!needFiltering(context, item))
????????????????return null;
? ? ? ? Point size = PhotoMetadataUtils
????????????????????????????.getBitmapBound(context.getContentResolver(),?
????????????????????????????item.getContentUri());
? ? ? ????? if (size.x mMaxSize) {
????????????????????????????return new IncapableCause(IncapableCause.DIALOG,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? context.getString(R.string.error_gif, mMinWidth,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String.valueOf(PhotoMetadataUtils
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?.getSizeInMB(mMaxSize))));
? ? ? ????? }
????????return null;
? ? }
}
//Glide4
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.request.RequestOptions;
import com.zhihu.matisse.engine.ImageEngine;
/**
* {@link ImageEngine} implementation using Glide.
*/
public class Glide4Engineimplements ImageEngine {
@Override
? ? public void loadThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri) {
????????Glide.with(context)
????????????????????.asBitmap()// some .jpeg files are actually gif
????? ? ? ? ? ? ? ? .load(uri)
????????????????????.apply(new RequestOptions()
????????????????????.override(resize, resize)
????????????????????.placeholder(placeholder)
????????????????????.centerCrop())
????????????????????.into(imageView);
? ? }
@Override
? ? public void loadGifThumbnail(Context context, int resize, Drawable placeholder, ImageView imageVie , Uri uri) {
????????????????????Glide.with(context)
????????????????????????????????.asBitmap()// some .jpeg files are actually gif
????????????????? ? ? ? ? ? ? ? .load(uri)
????????????????????????????????.apply(new RequestOptions()
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .override(resize, resize)
????????????????????????????????.placeholder(placeholder)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .centerCrop())
????????????????????????????????.into(imageView);
? ? }
@Override
? ? public void loadImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {
????????Glide.with(context)
????????????.load(uri)
????????????.apply(new RequestOptions()
????????????.override(resizeX, resizeY)
????????????.priority(Priority.HIGH)
????????????.fitCenter())
????????????.into(imageView);
? ? }
@Override
? ? public void loadGifImage(Context context, int resizeX, int resizeY, ImageView imageView, Uri uri) {
????????Glide.with(context)
????????????.asGif()
????????????.load(uri)
????????????.apply(new RequestOptions()
????????????.override(resizeX, resizeY)
????????????.priority(Priority.HIGH)
????????????.fitCenter())
????????????.into(imageView);
? ?}
@Override
? ? public boolean supportAnimatedGif() {
????????????return true;
? ? }
}
我們可以在平常的 Activity 或 Fragment 中啟動 MatisseActivity
Matisse.from(EdiUserInfoActivity.this)
????.choose(MimeType.ofAll())
????.countable(true)
????.maxSelectable(9)
????.addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))
.????gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.picsize))
????.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
????.thumbnailScale(0.85f)
????.imageEngine(new Glide4Engine())//Glide4
????.forResult(REQUEST_CODE_CHOOSE);
3、接收選擇的結果
在啟動圖片選擇器的 Activity 或 Fragment 中的 onActivityResult() 進行結果的回調處理
//activity回調
ListmSelected;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
? ? if (requestCode ==REQUEST_CODE_CHOOSE && resultCode ==RESULT_OK) {
mSelected = Matisse.obtainResult(data);
? ? ? ? Log.d("Matisse", "mSelected: " +mSelected);
? ? }
}
二佣渴、常用的 API
Mime 類型
Matisse 支持以下的 mime 類型
Mime typeFile extensionsMedia type??
?image/jpegjpg, jpegimage
image/pngpngimage
image/gifgifimage
imagex-ms-bmpbmpimage
video/mpegmpeg, mpgvideo
video/mp4mp4, m4vvideo
video/quicktimemovvideo
video/3gpp3gp, 3gppvideo
video/3gpp23g2, 3gpp2video
video/x-matroskamkvvideo
video/webmwebmvideo
video/mp2tstsvideo
video/aviavivideo
默認情況下辫狼,所有的圖像和視頻都將顯示在 Matisse 中,而且你并不能通過以下方法來限制可選擇的 mime 類型:
MimeType.ofAll()
MimeType.of(MimeType type, MimeType... rest)
MimeType.ofImage()
MimeType.ofVideo()
不過你可以讓 Matisse 只顯示一種媒體類型辛润,如果
啟動的時候膨处,調用?showSingleMediaType(true)
只選擇圖片或者視頻
數(shù)量
默認情況
在縮略圖的右上角有一個復選標記,讓你不僅可以選擇一個圖像
自動增長的數(shù)目
使用?countable(true)?來顯示一個從 1 開始的數(shù)字
最大的數(shù)字數(shù)量
使用?maxSelectable(int maxSelectable)?來限制可選擇的最大數(shù)目
方向
使用?restrictOrientation*(@ScreenOrientation int orientation)?來設置圖像選擇和預覽活動所需的方向。
網(wǎng)格的規(guī)格
如果你想要固定的跨度計數(shù)真椿,請使用?spanCount(int spanCount)鹃答,當方向更改時,范圍計數(shù)將保持不變突硝。
如果希望可以靈活地適應不同屏幕的網(wǎng)格大小测摔,請使用?spanCount(int spanCount),該值不一定被應用解恰,因為圖片網(wǎng)格應該填滿視圖容器锋八。測量的圖片網(wǎng)格的大小將盡可能接近該值。
縮略圖縮放
使用?thumnailScale(float scale)?來設置縮略圖位圖相對于視圖大小的縮放比例护盈,而且它應該是(0.0挟纱,1.0)中的浮點值。
三腐宋、主題
內置的主題
在 Matisse 中有兩種內置的主題:
Zhihu(亮藍色主題)
Dracula(黑色主題)
當啟動 Matisse 的時候紊服,調用 theme(@styleRes int themeId) 方法來使用其中一種主題
Matisse.from(MainActivity.this)? ? ...? ? .theme(R.style.Matisse_Zhihu | R.style.Matisse_Dracula)? ? .forResult(REQUEST_CODE_CHOOSE);
自定義主題
從兩個內置主題,甚至是他們的父母派生自定義主題胸竞,你可以自定義 Matisse 的外觀
這些屬性(在 attrs.xml 中定義)可以修改:
屬性作用
colorPrimary應用欄的顏色
colorPrimaryDark狀態(tài)欄的較暗變體
toolbar: toolbartoolbar 的風格
album.dropdown.title.color專輯名稱下的專輯中的下拉列表中的顏色
album.dropdown.count.color工具欄元素的顏色围苫,元素包括導航圖標,所選的相冊標題和右側的下拉箭頭圖標
album.thumbnail.placeholder相冊縮略圖的占位符
album.emptyView繪制圖片的空視圖
album.emptyView.textColor空白視圖的文字顏色
item.placeholder媒體網(wǎng)格的占位符顏色或 drawable
page.bgActivity 或 Fragment 頁面的背景顏色或 drawable
bottomToolbar.preview.textColor底部工具欄的背景顏色或 drawable
bottomToolbar.apply.textColor預覽按鈕文本的底部工具欄上的顏色
listPopupWindwoStyle專輯列表的下拉菜單樣式
capture.textColor可能出現(xiàn)在頂部的捕獲網(wǎng)格的文本顏色
以上便是本文的全部內容撤师,如果想進一步了解 Matisse 的源碼實現(xiàn)剂府,可以看下這篇文章:知乎 Matisse 源碼解析,帶你探究高效圖片選擇庫的秘密