android仿最新6.2版本微信相簿

來源:互聯網
上載者:User

android仿最新6.2版本相簿

仿相簿選擇圖片,查看大圖,寫的不太好,希望評論指出不足,諒解,先介紹一下我的基本思路

第一步擷取手機上的所有圖片路徑:

 

                Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;                ContentResolver contentResolver = getContentResolver();                //擷取jpeg和png格式的檔案,並且按照時間進行倒序                Cursor cursor = contentResolver.query(uri, null, MediaStore.Images.Media.MIME_TYPE + "=\"image/jpeg\" or " +                        MediaStore.Images.Media.MIME_TYPE + "=\"image/png\"", null, MediaStore.Images.Media.DATE_MODIFIED+" desc");                if (cursor != null){                    while (cursor.moveToNext()){                        //do something                    }                    handler.sendEmptyMessage(0);                }

 

我的儲存格式

 

    /** 按時間排序的所有圖片list */    private ArrayList allImages;    /** 按目錄排序的所有圖片list */    private ArrayList imageDirectories;     /**     * 一個檔案夾中的圖片資料實體     */    private class SingleImageDirectories{        /** 父目錄的路徑 */        public String directoryPath;        /** 目錄下的所有圖片實體 */        public ImageDirectoryModel images;    }

一個是全部圖片的儲存順序,第二個是按照目錄的圖片儲存順序

 

第二步,擷取到圖片之後,放入到gridview中進行顯示,但是BitmapFactory.decodeFile()函數會非常耗時,所以為了使得非常流暢的顯示圖片,建立一個類AlbumBitmapCacheHelper.class,用來非同步載入圖片,

該類使用LruCache cache來緩衝Bitmap,使得儲存圖片不會造成oom,我這裡設定cache的初始大小為1/4的運行時記憶體

然後使用ThreadPoolExecutor線程池來處理圖片的顯示,線程池大小應該設定適中

做完這兩件事情之後就可以用來載入圖片了,方法getBitmap用來講

        Bitmap bitmap = getBitmapFromCache(path, width, height);        //如果能夠從緩衝中擷取符合要求的圖片,則直接回調        if (bitmap != null) {        } else {            //建立線程放入線程池去處理該圖片的顯示        }        return bitmap;

如果cache中找不到該圖片,則調用BitmapFactory.decodeFile()去載入圖片,載入圖片不能夠直接載入原圖,會造成OOM,所以要去處理壓縮比

 

                        BitmapFactory.Options options = new BitmapFactory.Options();                        options.inJustDecodeBounds = true;                        BitmapFactory.decodeFile(path, options);                        options.inSampleSize = computeScale(options, width, height);                        options.inJustDecodeBounds = false;                        bitmap = BitmapFactory.decodeFile(path, options);                        //擷取之後,放入緩衝,以便下次繼續使用                        if (bitmap != null && cache!=null) {                            cache.put(path, bitmap);                        }

方法computeScale()主要是計算圖片最小的壓縮比,

 


這樣在gridview中的getview方法中去調用AlbumBitmapCacheHelper.class的getBitmap方法即可, 但是這樣會有很多的問題:
一個問題就是圖片顯示會閃,這主要是由於getview的view的複用,解決方案就是使用settag方法holder.iv_content.setTag(path);將要顯示的Imageview的tag設定為需要顯示的圖片路徑,這樣在回調的時候使用方法gridView.findViewWithTag(path),找到這個imageview進行顯示,閃的問題就解決了

第二個問題就是載入速度很慢,拉的速度很快的情況下,圖片要很久才會載入出來,特別是很大的圖片,比如拍照和的照片,
解決方案第一方案就是在AlbumBitmapCacheHelper類中維護一個ArrayList currentShowString,在getview方法中,如果該圖片要顯示,則直接將path加入到該list中,同時如果這個view的tag不為空白,說明該view的原來的path是不需要顯示的,所以需要將這個path從list中刪除:

//最佳化顯示效果 if(holder.iv_content.getTag() != null) { String remove = (String) holder.iv_content.getTag(); AlbumBitmapCacheHelper.getInstance().removePathFromShowlist(remove); } AlbumBitmapCacheHelper.getInstance().addPathToShowlist(path);
這樣線上程池中的處理方式就是先查看需要顯示的path是否在list中,如果沒有在list中,則該線程直接關閉,如果在list中,則顯示該圖片

if (!currentShowString.contains(path)||cache==null) { return; }


第二個方案就是如果顯示的圖片很大,特別是拍照,和解圖的圖片,decode有時會耗時幾秒中,顯示效果非常好,我自己想出來的處理的方式就是
***第一步,從應用的緩衝temp目錄下取,如果取不到,***第二步,計算圖片的壓縮比例samplesize,如果samplesize < 4,圖片的BitmapFactory.decodeFile()時間短,直接返回圖片,但是如果 samplesize > 4,執行第三步***第三步則將壓縮後的圖片存入temp目錄下,以便下次快速取出這樣顯示圖片的效果就出來了,顯示的速度除了和一樣第一次大圖載入慢之外,之後的顯示就能很快了,

 

                     if (!new File(CommonUtil.getDataPath()).exists())                        new File(CommonUtil.getDataPath()).mkdirs();                    //臨時檔案的檔案名稱                    String tempPath = CommonUtil.getDataPath() + hash + ".temp";                    //如果該檔案存在                    if (new File(tempPath).exists())                        bitmap = BitmapFactory.decodeFile(tempPath);                    ......                    //第三步,如果縮放比例大於4,該圖的載入會非常慢,所以將該圖儲存到臨時目錄下以便下次的快速載入                        if (options.inSampleSize >= 4) {                            try {                                File file = new File(tempPath);                                if (!file.exists())                                    file.createNewFile();                                FileOutputStream fos = new FileOutputStream(file);                                ByteArrayOutputStream baos = new ByteArrayOutputStream();                                bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);                                fos.write(baos.toByteArray());                                fos.flush();                                fos.close();                            } catch (FileNotFoundException e) {                                e.printStackTrace();                            } catch (IOException e) {                                e.printStackTrace();                            }                        }

問題就差不多解決了

第三步大圖的查看,大圖只要是使用的網上找的ZoomImageView+viewpagger的組合,但是使用這個出現的問題就是很容易OOM,沒辦法,我的處理方式就是在點進去大圖的時候

 

 

public void releaseHalfSizeCache() {    cache.resize((int) (Runtime.getRuntime().maxMemory() / 1024 / 8));}

直接將cache的大小變成原來的一半,因為查看大圖頁,載入一張大圖佔用的記憶體就很大,這樣顯示效果頁還湊合,有別的方法,一定要留言告訴我

注意:大圖的查看由於需要通過intent傳遞資料,但是intent傳遞的資料大小不能太大,如果手機上有幾千張圖片,則資料量大小可能會超過intent所能傳遞的最大量,所以可以寫入一個公用的地方,記憶體,資料庫,檔案都可以,

//TODO 這裡由於涉及到intent傳遞的資料不能太大的問題,所以如果需要,這裡要進行另外的處理,寫入到記憶體或者寫入到檔案中  intent.putExtra(PickBigImagesActivity.EXTRA_DATA, getAllImagesFromCurrentDirectory());

我暫時沒有處理~~

 

第四步就是圖片選擇完成之後,完成善後工作,將AlbumBitmapCacheHelper類中cache清空,差不多就這樣了,還有很多的小問題,比片時間的顯示,具體大家看源碼

 


 

源碼下載點我

由於源碼是android studio的工程,所以不能直接匯入eclipse,必須要手動拷貝檔案,在這裡放出所有的檔案,方便eclipse

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.