Android實現(xiàn)簡單圖庫輔助器
寫在前面
實際開發(fā)經(jīng)常會遇到讀取相冊或者拍照功能,網(wǎng)上也很非常多圖庫框架,都各有風格,也因此與自己的項目格格不入。再者,框架API太多,需要的配置太多,還要吃力研究。所以,本人摸索大多圖庫框架,提煉核心,寫一個只提供核心的輔助類,剩下的就可以自行玩耍。
實現(xiàn)步驟
第一步,創(chuàng)建輔助類,使用弱引用持有Activity,防止內(nèi)存溢出。
public class GalleryHelper{
private Activity mActivity;
public GalleryHelper(Activity activity) {
mActivity = new WeakReference<>(activity).get();
}
}
第二步,創(chuàng)建文件夾實體類,代表文件夾數(shù)據(jù)。paths集合是文件夾下的所有路徑。
public final class FolderEntity {
private int num;
private String name;
private List<String> paths = new ArrayList<>();
public int getNum() {
return paths.size();
}
public List<String> getPaths() {
return paths;
}
public void setName(String name) {
this.name = name;
}
}
第三步,首先獲取手機所有的圖片,在Activity里有getLoaderManager方法獲取一個LoaderManager實例,該類用于異步加載手機內(nèi)數(shù)據(jù)監(jiān)測,這里不做多分析。我們調(diào)用它的initLoader方法,前兩個參數(shù)這里不需要,只要實現(xiàn)LoaderCallbacks接口,并且指定Cursor類型。LoaderCallbacks接口有三個覆蓋方法,我們需要用到的是onCreateLoader方法和onLoadFinished方法,前者是初始化Loader,后者是加載完成后的回調(diào)。
mActivity.getLoaderManager().initLoader(0, null, new LoaderManager.LoaderCallbacks<Cursor>() {
@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
});
在onCreateLoader方法里,初始化CursorLoader,參數(shù)跟Cursor類下的query一樣,第一個參數(shù)指定外部村粗多媒體URI;第二個參數(shù)是查找結果字段,這里只要了路徑;第三個參數(shù)和第四個參數(shù)是搜索條件,條件為搜索jpeg格式和png格式,最后一個是按時間倒序搜索。
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(mActivity,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media.DATA},
MediaStore.Images.Media.MIME_TYPE + "=? or "
+ MediaStore.Images.Media.MIME_TYPE + "=?",
new String[]{"image/jpeg", "image/png"},
MediaStore.Images.Media.DATE_ADDED + " DESC");
}
CursorLoader初始化完成之后,搜索的結果會回調(diào)在onLoadFinished方法。這時就可以處理搜索出來的圖片路徑。因為圖片路徑是沒有分類,這里采用HashMap分類,以文件夾路徑為key,具體文件夾FolderEntity類為value,如果當前圖片路徑的文件夾不存在則創(chuàng)建FolderEntity并且放入HashMap,存在則獲取FolderEntity。
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
HashMap<String, FolderEntity> folderEntityHashMap = new HashMap<String, FolderEntity>();
if (cursor != null) {
while (cursor.moveToNext()) {
//圖片路徑
String path = cursor.getString(
cursor.getColumnIndex(MediaStore.Images.Media.DATA));
// 路徑不存在或者文件不存在就跳過
File file = new File(path);
if (TextUtils.isEmpty(path) || !file.exists()) {
continue;
}
String folerPath = file.getParent();
FolderEntity folderEntity;
if (folderEntityHashMap.containsKey(folerPath)) {
folderEntity = folderEntityHashMap.get(folerPath);
} else {
folderEntity = new FolderEntity();
folderEntityHashMap.put(file.getParentFile().getName(), folderEntity);
}
folderEntity.getPaths().add(path);
}
cursor.close();
}
}
但是數(shù)據(jù)是要提供給外部的,HashMap就顯得很麻煩,所以要轉(zhuǎn)換ArrayList,并且按數(shù)量大小進行順序。
private ArrayList<FolderEntity> map2List(HashMap<String, FolderEntity> mediaBeanMap) {
Iterator<FolderEntity> iterator = mediaBeanMap.values().iterator();
ArrayList<FolderEntity> list = new ArrayList<FolderEntity>();
while (iterator.hasNext()) {
list.add(iterator.next());
}
Collections.sort(list, new Comparator<FolderEntity>() {
@Override
public int compare(FolderEntity lhs, FolderEntity rhs) {
return lhs.getNum() > rhs.getNum() ? 1 : -1;
}
});
return list;
}
使用接口將數(shù)據(jù)提供給外部。
public interface GalleryCallback {
void complete(List<FolderEntity> list);
}
callback.complete(map2List(folderEntityHashMap));
第四步是實現(xiàn)拍照功能,這里實現(xiàn)是創(chuàng)建文件再啟動拍照功能。
File imageStoreDir = new File(Environment.getExternalStorageDirectory(),
"/DCIM/" + mActivity.getResources().getString(R.string.app_name));
if (!imageStoreDir.exists()) {
imageStoreDir.mkdir();
}
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (captureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
String filename = String.format("IMG%s", dateFormat.format(new Date()));
imagePath = new File(imageStoreDir, filename).getAbsolutePath();
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(imagePath)));
mActivity.startActivityForResult(new Intent(
MediaStore.ACTION_IMAGE_CAPTURE), REQUEST_CODE);
}
定義回調(diào)接口,接收Activit的onActivityResult方法,表示回調(diào)成功把上面創(chuàng)建好的文件路徑提供外部。
public interface CameraCallback {
void complete(String path);
}
public void onActivityResult(int requestCode, int resultCode) {
if (Activity.RESULT_OK == resultCode && REQUEST_CODE == requestCode) {
if (cameraCallback != null) {
cameraCallback.complete(imagePath);
}
}
}
外部調(diào)用
galleryHelper = new GalleryHelper(this);
galleryHelper.loadImages(new GalleryHelper.GalleryCallback() {
@Override
public void complete(List<FolderEntity> list) {
//加載本地圖片返回結果
}
});
findViewById(R.id.btn_camera).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
galleryHelper.openCamera(new GalleryHelper.CameraCallback() {
@Override
public void complete(String path) {
//拍照返回結果
}
});
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//使用拍照,必須接收Activity的onActivityResult方法
galleryHelper.onActivityResult(requestCode, resultCode);
}
別忘了加權限,這里為了簡單實現(xiàn),我把targetSdkVersion設置23以下,23和23以上的需要自行加上動態(tài)權限。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
整體就完成了,使用非常方便,有了這圖庫輔助器就可以自定義風格,再也不用受約束。網(wǎng)上大多開源圖片選擇器的搜索圖片都是如此,但這例子難免有bug,不足之處望指教。
github地址:https://github.com/tanxinye/GalleryHelper
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android實現(xiàn)SQLite添加、更新及刪除行的方法
這篇文章主要介紹了Android實現(xiàn)SQLite添加、更新及刪除行的方法,涉及Android基于SQLiteDatabase類操作SQLite數(shù)據(jù)庫的基本技巧,需要的朋友可以參考下2016-08-08
老生常談Android HapticFeedback(震動反饋)
下面小編就為大家?guī)硪黄仙U凙ndroid HapticFeedback(震動反饋)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-04-04
Android實現(xiàn)倒計時結束后跳轉(zhuǎn)頁面功能
最近在工作中遇到一個需求,需要在倒計時一段時間后進行跳轉(zhuǎn)頁面,通過查找相關資料發(fā)現(xiàn)其中涉及的知識還不少,所以分享出來,下面這篇文章主要給大家介紹了關于Android實現(xiàn)倒計時結束后跳轉(zhuǎn)頁面功能的相關資料,需要的朋友可以參考下。2017-11-11
Kotlin RadioGroup與ViewPager實現(xiàn)底層分頁按鈕方法
安卓的控件是挺多的,沒有辦法一個一個的來說明,我們挑出了一些重點的控件,組成一些常見的布局,這樣以后在遇到相同功能的界面時,就會有自己的思路,或者進行復用2022-12-12
Android studio 解決logcat無過濾工具欄的操作
這篇文章主要介紹了Android studio 解決logcat無過濾工具欄的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04

