国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > Android > 正文

Android實(shí)現(xiàn)簡(jiǎn)單圖庫(kù)輔助器

2019-12-12 03:10:41
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

寫(xiě)在前面

實(shí)際開(kāi)發(fā)經(jīng)常會(huì)遇到讀取相冊(cè)或者拍照功能,網(wǎng)上也很非常多圖庫(kù)框架,都各有風(fēng)格,也因此與自己的項(xiàng)目格格不入。再者,框架API太多,需要的配置太多,還要吃力研究。所以,本人摸索大多圖庫(kù)框架,提煉核心,寫(xiě)一個(gè)只提供核心的輔助類(lèi),剩下的就可以自行玩耍。

實(shí)現(xiàn)步驟

第一步,創(chuàng)建輔助類(lèi),使用弱引用持有Activity,防止內(nèi)存溢出。

  public class GalleryHelper{    private Activity mActivity;    public GalleryHelper(Activity activity) {      mActivity = new WeakReference<>(activity).get();    }  }

第二步,創(chuàng)建文件夾實(shí)體類(lèi),代表文件夾數(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;  }}

第三步,首先獲取手機(jī)所有的圖片,在Activity里有g(shù)etLoaderManager方法獲取一個(gè)LoaderManager實(shí)例,該類(lèi)用于異步加載手機(jī)內(nèi)數(shù)據(jù)監(jiān)測(cè),這里不做多分析。我們調(diào)用它的initLoader方法,前兩個(gè)參數(shù)這里不需要,只要實(shí)現(xiàn)LoaderCallbacks接口,并且指定Cursor類(lèi)型。LoaderCallbacks接口有三個(gè)覆蓋方法,我們需要用到的是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類(lèi)下的query一樣,第一個(gè)參數(shù)指定外部村粗多媒體URI;第二個(gè)參數(shù)是查找結(jié)果字段,這里只要了路徑;第三個(gè)參數(shù)和第四個(gè)參數(shù)是搜索條件,條件為搜索jpeg格式和png格式,最后一個(gè)是按時(shí)間倒序搜索。

  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初始化完成之后,搜索的結(jié)果會(huì)回調(diào)在onLoadFinished方法。這時(shí)就可以處理搜索出來(lái)的圖片路徑。因?yàn)閳D片路徑是沒(méi)有分類(lèi),這里采用HashMap分類(lèi),以文件夾路徑為key,具體文件夾FolderEntity類(lèi)為value,如果當(dāng)前圖片路徑的文件夾不存在則創(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));          // 路徑不存在或者文件不存在就跳過(guò)          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ù)量大小進(jìn)行順序。

    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));

第四步是實(shí)現(xiàn)拍照功能,這里實(shí)現(xiàn)是創(chuàng)建文件再啟動(dò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) {        //加載本地圖片返回結(jié)果      }    }); 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) {         //拍照返回結(jié)果         }       });     }   });  @Override  protected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    //使用拍照,必須接收Activity的onActivityResult方法    galleryHelper.onActivityResult(requestCode, resultCode);  }

別忘了加權(quán)限,這里為了簡(jiǎn)單實(shí)現(xiàn),我把targetSdkVersion設(shè)置23以下,23和23以上的需要自行加上動(dòng)態(tài)權(quán)限。

  <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" />

整體就完成了,使用非常方便,有了這圖庫(kù)輔助器就可以自定義風(fēng)格,再也不用受約束。網(wǎng)上大多開(kāi)源圖片選擇器的搜索圖片都是如此,但這例子難免有bug,不足之處望指教。

github地址:https://github.com/tanxinye/GalleryHelper

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 遵义市| 顺义区| 平江县| 蓝田县| 昌乐县| 正宁县| 砀山县| 凯里市| 鄂尔多斯市| 冷水江市| 娄烦县| 孝昌县| 白沙| 玛多县| 宣恩县| 永吉县| 班玛县| 南京市| 石景山区| 台东县| 肥西县| 晴隆县| 星座| 新昌县| 鹤壁市| 文成县| 新野县| 武陟县| 明溪县| 镇江市| 南城县| 潍坊市| 迭部县| 兴义市| 银川市| 青冈县| 团风县| 丹江口市| 兴国县| 沂水县| 徐州市|