知乎开源框架Matisse

xiaoxiao2025-09-01  8

Matisse

过滤器

GifSizeFilter

package function.matisse; import android.content.Context; import android.graphics.Point; import com.self.zsp.dfs.R; import com.zhihu.matisse.MimeType; import com.zhihu.matisse.filter.Filter; import com.zhihu.matisse.internal.entity.IncapableCause; import com.zhihu.matisse.internal.entity.Item; import com.zhihu.matisse.internal.utils.PhotoMetadataUtils; import java.util.HashSet; import java.util.Set; /** * @decs: GifSizeFilter * @date: 2018/10/25 15:45 */ public class GifSizeFilter extends 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 Set<MimeType> constraintTypes() { return new HashSet<MimeType>() {{ add(MimeType.GIF); }}; } @Override public IncapableCause filter(Context context, Item item) { if (!needFiltering(context, item)) { return null; } Point size = PhotoMetadataUtils.getBitmapBound(context.getContentResolver(), item.getContentUri()); if (size.x < mMinWidth || size.y < mMinHeight || item.size > mMaxSize) { return new IncapableCause(IncapableCause.DIALOG, context.getString(R.string.errorGif, mMinWidth, String.valueOf(PhotoMetadataUtils.getSizeInMB(mMaxSize)))); } return null; } } .addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))

ImageSizeFilter

package function.matisse; import android.content.Context; import android.graphics.Point; import com.self.zsp.dfs.R; import com.zhihu.matisse.MimeType; import com.zhihu.matisse.filter.Filter; import com.zhihu.matisse.internal.entity.IncapableCause; import com.zhihu.matisse.internal.entity.Item; import com.zhihu.matisse.internal.utils.PhotoMetadataUtils; import java.util.HashSet; import java.util.Set; /** * Created on 2018/10/26. * * @desc ImageSizeFilter */ public class ImageSizeFilter extends Filter { private int mMinWidth; private int mMinHeight; private int mMaxSize; public ImageSizeFilter(int minWidth, int minHeight, int maxSizeInBytes) { mMinWidth = minWidth; mMinHeight = minHeight; mMaxSize = maxSizeInBytes; } @Override protected Set<MimeType> constraintTypes() { /*return EnumSet.of(MimeType.JPEG, MimeType.PNG, MimeType.BMP, MimeType.WEBP);*/ return new HashSet<MimeType>() {{ add(MimeType.WEBP); add(MimeType.PNG); add(MimeType.MPEG); add(MimeType.JPEG); add(MimeType.BMP); }}; } @Override public IncapableCause filter(Context context, Item item) { if (!needFiltering(context, item)) { return null; } Point size = PhotoMetadataUtils.getBitmapBound(context.getContentResolver(), item.getContentUri()); if (size.x < mMinWidth || size.y < mMinHeight || item.size > mMaxSize) { // IncapableCause.TOAST、IncapableCause.DIALOG、IncapableCause.NONE return new IncapableCause(IncapableCause.NONE, context.getString(R.string.errorFile, mMinWidth, String.valueOf(PhotoMetadataUtils.getSizeInMB(mMaxSize)))); } return null; } } .addFilter(new ImageSizeFilter(320, 320, 5 * Filter.K * Filter.K))

引擎

PicassoEngine 自带。GlideEngine 基于implementation 'com.github.bumptech.glide:glide:4.8.0'。平板正常,手机报错。

For Glide V4

To be honest,the library can’t supply GlideEngine for Glide both v3 and v4 at the same time. (Anyone who have good idea to achieve this. PR is welcomed)

GlideEngine with Glide v3 is default.

So if your project’s glide version is 4.0+ ,then you must realize GlideEngine by yourself. More details could refer with Glide4Engine in the sample.

package com.zsp.matisse.engine; 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; /** * Created on 2018/12/6. * * @author 郑少鹏 * @desc {@link ImageEngine} implementation using Glide.d */ public class Glide4Engine implements ImageEngine { @Override public void loadThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri) { Glide.with(context) // some .jpeg files are actually gif .asBitmap() .load(uri) .apply(new RequestOptions() .override(resize, resize) .placeholder(placeholder) .centerCrop()) .into(imageView); } @Override public void loadGifThumbnail(Context context, int resize, Drawable placeholder, ImageView imageView, Uri uri) { Glide.with(context) // some .jpeg files are actually gif .asBitmap() .load(uri) .apply(new RequestOptions() .override(resize, resize) .placeholder(placeholder) .centerCrop()) .into(imageView); } @Override public void loadImage(Context context, int xResize, int yResize, ImageView imageView, Uri uri) { Glide.with(context) .load(uri) .apply(new RequestOptions() .override(xResize, yResize) .priority(Priority.HIGH) .fitCenter()) .into(imageView); } @Override public void loadGifImage(Context context, int xResize, int yResize, ImageView imageView, Uri uri) { Glide.with(context) .asGif() .load(uri) .apply(new RequestOptions() .override(xResize, yResize) .priority(Priority.HIGH) .fitCenter()) .into(imageView); } @Override public boolean supportAnimatedGif() { return true; } }

依赖

implementation 'com.zhihu.android:matisse:0.5.3-beta3'

权限

android.permission.READ_EXTERNAL_STORAGE android.permission.WRITE_EXTERNAL_STORAGE

使用

MatisseKit

package com.zsp.matisse.kit; import android.app.Activity; import android.content.pm.ActivityInfo; import androidx.fragment.app.Fragment; import com.zhihu.matisse.Matisse; import com.zhihu.matisse.MimeType; import com.zhihu.matisse.internal.entity.CaptureStrategy; import com.zsp.matisse.R; import com.zsp.matisse.engine.Glide4Engine; import java.lang.ref.WeakReference; import timber.log.Timber; /** * Created on 2018/12/6. * * @author 郑少鹏 * @desc MatisseKit */ public class MatisseKit { /** * 请求码 */ public static final int REQUEST_CODE = 0x001; /** * 活动中Matisse准备 * * @param activity 活动 * @param maxCount 最大数 * @param authority 权威(如${applicationId}.fileprovider) */ public static void matisseOperateInActivity(Activity activity, int maxCount, String authority) { WeakReference<Activity> weakReference = new WeakReference<>(activity); Activity activityUse = weakReference.get(); Matisse.from(activityUse) .choose(MimeType.ofImage(), false) .countable(true) .capture(true) .captureStrategy(new CaptureStrategy(true, authority)) .maxSelectable(maxCount) .gridExpectedSize(activityUse.getResources().getDimensionPixelSize(R.dimen.dp_130)) .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) .thumbnailScale(0.85f) // for glide-V3 // .imageEngine(new GlideEngine()) // for glide-V4 .imageEngine(new Glide4Engine()) .setOnSelectedListener((uriList, pathList) -> { // DO SOMETHING IMMEDIATELY HERE Timber.d("onSelected: pathList = %s", pathList); }) .originalEnable(true) .maxOriginalSize(10) .autoHideToolbarOnSingleTap(true) .setOnCheckedListener(isChecked -> { // DO SOMETHING IMMEDIATELY HERE Timber.d("onCheck: isChecked = %s", isChecked); }) .forResult(REQUEST_CODE); } /** * 碎片中Matisse准备 * * @param fragment 碎片 * @param maxCount 最大数 * @param authority 权威(如${applicationId}.fileprovider) */ public static void matisseOperateInFragment(Fragment fragment, int maxCount, String authority) { Matisse.from(fragment) .choose(MimeType.ofImage(), false) .countable(true) .capture(true) .captureStrategy(new CaptureStrategy(true, authority)) .maxSelectable(maxCount) .gridExpectedSize(fragment.getResources().getDimensionPixelSize(R.dimen.dp_130)) .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) .thumbnailScale(0.85f) // for glide-V3 // .imageEngine(new GlideEngine()) // for glide-V4 .imageEngine(new Glide4Engine()) .setOnSelectedListener((uriList, pathList) -> { // DO SOMETHING IMMEDIATELY HERE Timber.d("onSelected: pathList = %s", pathList); }) .originalEnable(true) .maxOriginalSize(10) .autoHideToolbarOnSingleTap(true) .setOnCheckedListener(isChecked -> { // DO SOMETHING IMMEDIATELY HERE Timber.d("onCheck: isChecked = %s", isChecked); }) .forResult(REQUEST_CODE); } }

主代码

MatisseKit.matisseOperateInActivity(this, 1, getString(R.string.fileProviderAuthorities)); 或 MatisseKit.matisseOperateInFragment(this, 1, getString(R.string.fileProviderAuthorities)); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == MatisseKit.REQUEST_CODE) { List<Uri> mSelected = Matisse.obtainResult(data); 或 List<String> mSelected = Matisse.obtainPathResult(data); } }

Themes

官方

There are two built-in themes you can use to start MatisseActivity:

R.style.Matisse_Zhihu (light mode) R.style.Matisse_Dracula (dark mode)

And Also you can define your own theme as you wish.

自定义

<color name="zhihu_primary">#1E77EB</color> <color name="zhihu_primary_dark">#1E77EB</color> ...

注意

.addFilter(null)报错java.lang.IllegalArgumentException: filter cannot be null

转载请注明原文地址: https://www.6miu.com/read-5035589.html

最新回复(0)