著手實現(xiàn)一個圖片選擇器-PhotoPicker

相信很多朋友在開發(fā)安卓App時都會有這樣需求,圖片選擇或拍照選擇,需求實現(xiàn)很簡單,如下:

  • 圖片選擇:調用系統(tǒng)圖庫進行選擇
  • 拍照選擇:調用系統(tǒng)相機進行拍照

看了上面的實現(xiàn)后發(fā)現(xiàn)很容易啊,都有現(xiàn)成的調用;但我們錯了,對于產(chǎn)品的BT需求,我們遠遠無法這么簡單的滿足,比如:圖片多選上傳了?額,這個時候我們調用系統(tǒng)的圖庫就蒙B了,因為系統(tǒng)圖庫并不支持多選;那怎么辦了?不急,請慢慢往下看,這就是這篇Blog的意義所在,定義一個自己的圖片選擇器

本項目已經(jīng)開發(fā)完畢了,下面是相應的地址
GitHub:https://github.com/JaySong/PhotoPicker
Gradle引用:'com.jay.ui:photopicker:last-version';目前版本:1.0.0
此工程實現(xiàn)的功能:

  1. 圖片的單選或多選<可自定最大選擇數(shù)量>
  2. 可根據(jù)不同圖片文件夾進行篩選
  3. 圖片的預覽
  4. 相機拍照選擇
    總結:微信選擇圖片的功能基本都有,可滿足大部分需求,UI界面采用MD風格設計

需要解決的技術問題

  1. 得到手機中所有的圖片并顯示在列表
  2. 實現(xiàn)列表的單選或多選

1.得到手機中所有的圖片并顯示在列表

實現(xiàn):采用LoaderManager.LoaderCallbacks<Cursor>時行圖片的查詢,下面見核心代碼
PS:當前需要實現(xiàn)加載的類可實現(xiàn)此接口或自己自定義一個類實現(xiàn)此接口

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@SuppressWarnings("UnnecessaryLocalVariable")
CursorLoader cursorLoader = new CursorLoader(
this,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME},
"mime_type=? or mime_type=?" + (isShowGif ? "or mime_type=?" : ""),
isShowGif ? new String[]{"image/jpeg", "image/png", "image/gif"} : new String[]{"image/jpeg", "image/png"},
MediaStore.Images.Media.DATE_ADDED + " DESC"
);
return cursorLoader;
}

>getLoaderManager().initLoader(int,Bundle, LoaderManager.LoaderCallbacks);

通過此方法進行初始化,如果要兼容到11以下的系統(tǒng),調用
getSupportLoaderManager()..initLoader(int,Bundle, LoaderManager.LoaderCallbacks);

onCreateLoader()方法是接口中必須實現(xiàn)的方法;

new CursorLoader(Context context,
Uri uri, //查詢的Uri
String[] projection, //列名
String selection,//查詢條件
String[] selectionArgs, //查詢條件中的參數(shù)
String sortOrder)//排序規(guī)則

onLoadFinished(Loader<Cursor> loader, Cursor data)方法會在查詢完成后回調,其中data就是我們想要的結果就在此對象中

if (data.moveToFirst()) {
do {
String photoDir = data.getString(data.getColumnIndex(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME));
String photoUri = data.getString(data.getColumnIndex(MediaStore.Images.Media.DATA));
} while (data.moveToNext());
}
//photoDir:當前圖片所在的目錄名
//photoUri:當前圖片的路徑


2.實現(xiàn)列表的單選或多選

列表的顯示是使用控件RecyclerView實現(xiàn)展示,圖片選中控件是使用CheckBox來進行圖片的選擇標識,具體請查看源碼PhotoPickerActivity.PhotoListAdapter適配器類

拍照并顯示至列表

實現(xiàn)方式:同樣調用系統(tǒng)相機

//用戶要拍照
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePhotoFile = createImageFile();
// Continue only if the File was successfully created
if (takePhotoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(takePhotoFile));
startActivityForResult(takePictureIntent, TAKE_PHOTO);
} else {
showSnackBar(getString(R.string.open_camera_fail));
}
//其中createImageFile()返回一個文件File,即拍照后保存的路徑

拍照成功需要更新列表,這個時候我們做一個操作即可,那就是提醒系統(tǒng)更新媒體庫

public void notifyMediaUpdate(File file) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
//這樣操作后,我們前面實現(xiàn)的加載器會自動去加載新的數(shù)據(jù),參數(shù)file就是我們之前拍照前保存的保存路徑

下面上一張演示圖

1.gif
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容