Android選擇與上傳圖片之Matisse教程
效果圖:
就目前效果圖來看,好像也沒什么毛病哈,其實我這個集成的過程是有點坎坷的。
而且,功能也不算是很齊全吧…主要體現(xiàn)在以下幾個點
- 沒有回調(diào)之后的預(yù)覽
- 選擇之后不能刪除已選
- 已選擇的圖片再次選擇不能帶過去
- 剪裁
- 壓縮
- 權(quán)限
- Glide版本過低
但是,也是有特點的
- MD風(fēng)格
- 白天模式和夜間模式
其他與同類相比也真的沒什么了,唯一背書 就是知乎團隊出的唄。。
相比之下,昨天出的Android選擇與上傳圖片之PictureSelector教程就更加友好和人性化了。
下面來說說集成遇到的問題以及解決方案。
github:https://github.com/zhihu/Matisse
集成
Gradle:
repositories { jcenter() } dependencies { compile 'com.zhihu.android:matisse:0.4.3' }
releases最新是v0.5.0-beta3的,本文還是基于官方文檔0.4.3的版本
你以為這樣就可以使用了嗎,nonono,權(quán)限需要動態(tài)獲取,你還需要RxPermissions或者其他權(quán)限庫,或者自己封裝
compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'
這就完了嗎,no,你還需要rxjava
compile "io.reactivex.rxjava2:rxjava:2.1.9"
現(xiàn)在總可以了吧,依然nonono,如果你項目集成了Glide,還是會報錯,我在用的Glide版本是4.6.1的,Matisse中集成的是3.7.0的,是有區(qū)別的,具體你可以看這里 帶你全面了解Glide 4的用法,你也可以用Picasso。
會報異常
java.lang.NoSuchMethodError: com.bumptech.glide.RequestManager.load
解決方案就是重新自定義圖片加載方式GlideEngine,具體可以看這里Matisse 與 Glide – java.lang.NoSuchMethodError: com.bumptech.glide.RequestManager.load。
到這里你以為就ok了嗎,還是nonono,還是會報異常,因為兩個版本會沖突啊
java.lang.NoClassDefFoundError: android.support.v4.animation.AnimatorCompatHelper
解決方案看這里java.lang.NoClassDefFoundError: android.support.v4.animation.AnimatorCompatHelper
Matisse:愛我你怕了嗎
終于可以使用了,哇的哭出聲
使用
你以為集成都這么坎坷了,使用應(yīng)該很方便吧,no啊大胸弟,
雖然集成之前我看到150+的Issues有點頭皮發(fā)麻,果然沒讓我失望,坎坷的路還長著呢。
最快的方式集成第三方有兩種,1.看官方文檔,2.看例子。
你以為從sample中copy copy代碼,導(dǎo)下包就能跑起來了嗎,nonono
選擇器不光是有圖片的吧,你可能還有g(shù)if和視頻啊,所以在配置的時候你要選擇一個type啊
sample是這樣的
Matisse.from(SampleActivity.this) .choose(MimeType.ofAll(), false) ...
源碼實際上是這樣的
public SelectionSpecBuilder choose(Set<MimeType> mimeType) { return new SelectionSpecBuilder(this, mimeType); }
所以,你的應(yīng)該是這樣
Matisse.from(MainActivity.this) .choose(MimeType.allOf()) ...
沒有boolean類型參數(shù),而且也不是ofAll了,而是allOf。
上面是把所有的都列出來,那我如果只選圖片怎么辦呢
sample是這樣的
Matisse.from(SampleActivity.this) .choose(MimeType.ofImage()) ...
尼瑪。。實際上MimeType這個枚舉類中根本就沒有ofImage
所以你的應(yīng)該是這樣的
Matisse.from(MainActivity.this) .choose(MimeType.of(MimeType.JPEG)) ...
所以,刺不刺激?
對了,你如果要用最新版本,比如v0.5.0-beta3,注意去掉前面的v。
然后,你可以跑起來了,也不會報錯了,仿佛一切都ok的樣子(翻譯一下:其實并沒有,逃..)
遇到幾個點還沒有解決,也懶得深入研究了,我要回家過年,哼
- 拍照還是選擇相冊,沒有處理
- 預(yù)覽,選擇圖片的時候可以預(yù)覽,但是回調(diào)之后并不行,沒有處理
- onActivityResult回調(diào)之后的圖片不能直接刪除,沒有處理
- 剪裁,沒有處理
- 壓縮,沒有處理
- 哦對了,如果可以預(yù)覽了,那還得可以保存圖片呢,也沒有處理,因為預(yù)覽沒有處理,哈哈哈嗝
- 已選擇的圖片,再次選擇的時候帶過去,沒有處理
那有人就會說了,這么多沒有的功能,或者文檔沒有介紹到的,不是可以自己去處理嗎,這樣豈不是定制化更高?比如篩選條件、主題…
emmm…
你說的對,但我不認同。哈哈哈
哦對了,選擇圖片的時候可以預(yù)覽,看一下是什么樣的
啊。。scaleType不對就不說了,可是你讓我的toolbar兄弟如何自處?又要挨window爸爸的打了。。
哦對了,0.5的版本加了新功能,但是正式版還沒有發(fā)布
最后,不要忘了加權(quán)限和FileProvider。
然后貼一下MainActivity的代碼和gayhub的地址
package com.yechaoa.matissedemo; import android.Manifest; import android.content.Intent; import android.content.pm.ActivityInfo; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.Toast; import com.bumptech.glide.Glide; import com.tbruyelle.rxpermissions2.RxPermissions; import com.zhihu.matisse.Matisse; import com.zhihu.matisse.MimeType; import com.zhihu.matisse.internal.entity.CaptureStrategy; import java.util.List; import io.reactivex.Observer; import io.reactivex.disposables.Disposable; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private UriAdapter mAdapter; private static final int REQUEST_CODE_CHOOSE = 23; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.zhihu).setOnClickListener(this); findViewById(R.id.dracula).setOnClickListener(this); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview); recyclerView.setLayoutManager(new GridLayoutManager(this, 3)); recyclerView.setAdapter(mAdapter = new UriAdapter()); } /** * 1 預(yù)覽 2 已選擇帶過去 3 剪裁 4 壓縮 * <p> * 120 顯示三列 100顯示四列 */ @Override public void onClick(final View v) { RxPermissions rxPermissions = new RxPermissions(MainActivity.this); rxPermissions.request(Manifest.permission.WRITE_EXTERNAL_STORAGE) .subscribe(new Observer<Boolean>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(Boolean aBoolean) { if (aBoolean) { switch (v.getId()) { case R.id.zhihu: Matisse.from(MainActivity.this) .choose(MimeType.allOf())//ofAll() .theme(R.style.Matisse_Zhihu)//主題,夜間模式R.style.Matisse_Dracula .countable(true)//是否顯示選中數(shù)字 .capture(true)//是否提供拍照功能 .captureStrategy(new CaptureStrategy(true, "com.zhihu.matisse.sample.fileprovider"))//存儲地址 .maxSelectable(9)//最大選擇數(shù) //.addFilter(new GifSizeFilter(320, 320, 5 * Filter.K * Filter.K))//篩選條件 .gridExpectedSize(getResources().getDimensionPixelSize(R.dimen.grid_expected_size))//圖片大小 .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)//屏幕方向 .thumbnailScale(0.85f)//縮放比例 .imageEngine(new MyGlideEngine())//圖片加載方式 .forResult(REQUEST_CODE_CHOOSE);//請求碼 break; case R.id.dracula: Matisse.from(MainActivity.this) .choose(MimeType.of(MimeType.JPEG))//ofImage() .theme(R.style.Matisse_Dracula) .countable(false) .maxSelectable(9) .imageEngine(new MyGlideEngine()) .forResult(REQUEST_CODE_CHOOSE); break; } mAdapter.setData(null); } else { Toast.makeText(MainActivity.this, "權(quán)限被拒絕了..", Toast.LENGTH_LONG).show(); } } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) { mAdapter.setData(Matisse.obtainResult(data)); } } private class UriAdapter extends RecyclerView.Adapter<UriAdapter.UriViewHolder> { private List<Uri> mUris; void setData(List<Uri> uris) { mUris = uris; notifyDataSetChanged(); } @Override public UriViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new UriViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.uri_item, parent, false)); } @Override public void onBindViewHolder(UriViewHolder holder, int position) { Glide.with(MainActivity.this).load(mUris.get(position)).into(holder.mImg); } @Override public int getItemCount() { return mUris == null ? 0 : mUris.size(); } class UriViewHolder extends RecyclerView.ViewHolder { private ImageView mImg; UriViewHolder(View contentView) { super(contentView); mImg = (ImageView) contentView.findViewById(R.id.img); } } } }
github:https://github.com/yechaoa/MatisseDemo
到此這篇關(guān)于Android選擇與上傳圖片之Matisse教程的文章就介紹到這了,更多相關(guān)Android圖片選擇上傳Matisse內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 解決java.lang.NoClassDefFoundError: android.support.v4.animation.AnimatorCompatHelper問題
- Android選擇與上傳圖片之PictureSelector教程
- C++使用WideCharToMultiByte函數(shù)生成UTF-8編碼文件的方法
- SpringCloud2020.0.x版UnderTow AccessLog相關(guān)配置簡介
- 解決SpringBoot加載application.properties配置文件的坑
- C語言container of()函數(shù)案例詳解
- gaussdb 200安裝 data studio jdbc idea鏈接保姆級安裝步驟
- OpenCV實現(xiàn)特征檢測和特征匹配方法匯總
- easycom模式開發(fā)UNI-APP組件調(diào)用必須掌握的實用技巧
- C語言MultiByteToWideChar和WideCharToMultiByte案例詳解
- Android選擇與上傳圖片之ImagePicker教程
相關(guān)文章
Android中隱藏狀態(tài)欄和標題欄的方法匯總(隱藏狀態(tài)欄、標題欄的五種方法)
這篇文章主要介紹了Android中隱藏狀態(tài)欄和標題欄的方法匯總(隱藏狀態(tài)欄、標題欄的五種方法),非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02Android開發(fā)自學(xué)筆記(四):APP布局下
這篇文章主要介紹了Android開發(fā)自學(xué)筆記(四):APP布局下,本文是上一篇的補充,需要的朋友可以參考下2015-04-04Android中閃屏實現(xiàn)方法小結(jié)(普通閃屏、倒計時閃屏、倒計時+動畫閃屏)
這篇文章主要介紹了Android中閃屏實現(xiàn)方法小結(jié)(普通閃屏、倒計時閃屏、倒計時+動畫閃屏),非常不錯,代碼簡單易懂,需要的朋友可以參考下2017-01-01Android訪問php取回json數(shù)據(jù)實例
Android訪問php取回json數(shù)據(jù),實現(xiàn)代碼如下,遇到訪問網(wǎng)絡(luò)的權(quán)限不足在AndroidManifest.xml中,需要進行如下配置2013-06-06