天天看點

Android中仿微信選擇圖檔并展示在RecyclerView中

 Android圖檔選擇

大家都知道網上有很多第三方的圖檔選擇器,但是到了自己真正的項目中,可能會有不同的需求,需要自己去修改。是以我自己根據鴻洋大神的慕課網視訊寫了一個圖檔選擇器,又對代碼進行了修改,友善大家進行使用。

本項目主要設計思路就是:一個圖檔加載類(單例)+利用ContentProvider掃描手機的圖檔+GridView顯示圖檔 +RecyclerView在界面上顯示圖檔。

本項目的主要步驟有以下幾步:

1.圖檔加載類

2.掃描手機中的圖檔

3.選擇圖檔展示在recyclerview中

當然最重要的是:

1.盡可能的去避免記憶體溢出

2.使用者操作UI控件必須充分的流暢

3.使用者預期顯示的圖檔盡可能的快(圖檔的加載政策的選擇)LIFO

本項目的主要功能:

1.掃描手機中的圖檔,預設顯示圖檔最多的檔案夾,在底部顯示檔案夾的名字以及圖檔的數量。

2.點選底部,彈出popupWindow,此popupWindow顯示所有包含圖檔的檔案夾以及檔案夾的名字。

3.選擇檔案夾,進入圖檔選擇界面,點選選擇圖檔,再次點選取消。

4.點選右上方的“選擇”按鈕,将選擇的圖檔呈現在recyclerView中。

展示一下效果:

Android中仿微信選擇圖檔并展示在RecyclerView中

代碼展示及講解

1.圖檔加載類 ImageLoader(核心類)

本類是圖檔選擇器的核心類,該類為單例,可以設定圖檔加載打方式:

1.FIFO(先進先加載)

2.LILO(後進先加載)。 

調用該方法:ImageLoader.getInstance(最大圖檔加載并發數,ImageLoader.Type.FIFO(圖檔加載的方式)) 

.LoadImage(圖檔的本地存放路徑(絕對路徑), 要顯示圖檔的ImageView布局);

public class ImageLoader {
    private static ImageLoader mInStance;

    //圖檔緩存的核心對象
    private LruCache<String,Bitmap> mLruCache;

    //線程池
    private ExecutorService mThreadPool;
    private  static  final  int DEAFULT_THREAD_COUNT=1;
    //隊列的排程方式
    private  Type mType=Type.LIFO;
    //任務隊列
    private LinkedList<Runnable> mTaskQueue;
    //背景輪詢線程
    private  Thread mPoolThread;
    private Handler mPoolThreadHandler;
    //UI線程中的Handler
    private Handler mUIHandler;
    private Semaphore  mSemaphorePoolThreadHandler=new Semaphore(0);
    private Semaphore  mSemaphoreThreadPool;
    public  enum  Type{
        FIFO,LIFO;
    }

    public ImageLoader(int threadCount,Type type) {
          init(threadCount,type);
    }

    /**
     * 初始化
     * @param threadCount
     * @param type
     */
    private void init(int threadCount, Type type) {
        //背景輪詢線程
        mPoolThread=new Thread(){
            @Override
            public void run() {
                Looper.prepare();
                mPoolThreadHandler=new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        //線程池取出一個任務進行執行
                        mThreadPool.execute(getTask());
                        try {
                            mSemaphoreThreadPool.acquire();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                //釋放一個信号量
                mSemaphorePoolThreadHandler.release();
                Looper.loop();
            }
        };
        mPoolThread.start();
        //擷取我們應用的最大可用記憶體
        int maxMemory= (int) Runtime.getRuntime().maxMemory();
        int cacheMemory = maxMemory / 8;
        mLruCache=new LruCache<String,Bitmap>(cacheMemory){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes()*value.getHeight();
            }
        };
            mThreadPool= Executors.newFixedThreadPool(threadCount);
            mTaskQueue=new LinkedList<>();
            mType=type==null?Type.LIFO:type;
            mSemaphoreThreadPool=new Semaphore(threadCount);

    }

    /**
     * 從任務隊列取出一個方法
     * @return
     */
    private Runnable getTask() {
        if (mType==Type.FIFO){
            return mTaskQueue.removeFirst();
        }else if (mType==Type.LIFO){
            return mTaskQueue.removeLast();
        }
        return  null;
    }

    public  static  ImageLoader getInStance(){
        if (mInStance==null){
            synchronized (ImageLoader.class){
                if (mInStance==null){
                    mInStance=new ImageLoader(DEAFULT_THREAD_COUNT,Type.LIFO);
                }
            }
        }
        return  mInStance;
    }
    public  static  ImageLoader getInStance(int threadCount,Type type){
        if (mInStance==null){
            synchronized (ImageLoader.class){
                if (mInStance==null){
                    mInStance=new ImageLoader(threadCount,type);
                }
            }
        }
        return  mInStance;
    }

    /**
     * 根據path為imageview設定圖檔
     * @param path
     * @param imageView
     */
    public  void loadImage(final String path, final ImageView imageView){
        imageView.setTag(path);
        if (mUIHandler==null){
            mUIHandler=new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    //擷取得到的圖檔,為imageview回調設定圖檔
                    ImgBeanHolder holder= (ImgBeanHolder) msg.obj;
                    Bitmap bitmap = holder.bitmap;
                    ImageView imageview= holder.imageView;
                    String path = holder.path;
                    if (imageview.getTag().toString().equals( path)){
                        imageview.setImageBitmap(bitmap);
                    }
                }
            };
        }
        //根據path在緩存中擷取bitmap
        Bitmap bm=getBitmapFromLruCache(path);
        if (bm!=null){
            refreshBitmap(bm, path, imageView);
        }else{
            addTask(new Runnable(){
                @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
                @Override
                public void run() {
                    //加載圖檔
                    //圖檔的壓縮
                    //1.獲得圖檔需要顯示的大小
                  ImageSize imageSize=  getImageViewSize(imageView);
                    //壓縮圖檔
                    Bitmap bm=decodeSampledBitmapFromPath(imageSize.width,imageSize.height,path);
                    //把圖檔加入到緩存
                    addBitmapToLruCache(path,bm);
                    //
                    refreshBitmap(bm, path, imageView);
                    mSemaphoreThreadPool.release();
                }
            });
        }

    }

    private void refreshBitmap(Bitmap bm, String path, ImageView imageView) {
        Message message = Message.obtain();
        ImgBeanHolder holder=new ImgBeanHolder();
        holder.bitmap=bm;
        holder.path=path;
        holder.imageView=imageView;
        message.obj=holder;
        mUIHandler.sendMessage(message);
    }

    /**
     * 将圖檔加入到LruCache
     * @param path
     * @param bm
     */
    private void addBitmapToLruCache(String path, Bitmap bm) {
        if (getBitmapFromLruCache(path)==null){
            if (bm!=null){
                mLruCache.put(path,bm);
            }
        }
    }

    /**
     * 根據圖檔需要顯示的寬和高進行壓縮
     * @param width
     * @param height
     * @param path
     * @return
     */
    private Bitmap decodeSampledBitmapFromPath(int width, int height, String path) {
       //獲得圖檔的寬和高,并不把圖檔加載到記憶體中
        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(path,options);

        options.inSampleSize=caculateInSampleSize(options,width,height);

        //使用獲得到的InSampleSize再次解析圖檔
        options.inJustDecodeBounds=false;
        Bitmap bitmap=BitmapFactory.decodeFile(path,options);
        return  bitmap;

    }

    /**
     * 根據需求的寬和高以及圖檔實際的寬和高計算SampleSize
     * @param options
     * @param width
     * @param height
     * @return
     */
    private int caculateInSampleSize(BitmapFactory.Options options, int width, int height) {
        int outWidth = options.outWidth;
        int outHeight = options.outHeight;
        int inSampleSize=1;
        if (outWidth>width||outHeight>height){
            int widthRadio=Math.round(outWidth*1.0f/width);
            int heightRadio=Math.round(outHeight*1.0f/height);
            inSampleSize=Math.max(widthRadio,heightRadio);
        }

        return inSampleSize;
    }

    /**
     *根據ImageView獲得适當的壓縮的寬和高
     * @param imageView
     */
    private ImageSize getImageViewSize(ImageView imageView) {
        ImageSize imageSize=new ImageSize();

        DisplayMetrics displayMetrics = imageView.getContext().getResources().getDisplayMetrics();
        ViewGroup.LayoutParams lp = imageView.getLayoutParams();
     //  int width=(lp.width== ViewGroup.LayoutParams.WRAP_CONTENT?0:imageView.getWidth());
       int width = imageView.getWidth();//擷取imageview的實際寬度
        if (width <=0){
            width=lp.width;//擷取imageview再layout聲明的寬度
        }
        if (width<=0){
            width= getImageViewFieldValue(imageView,"mMaxWidth");//檢查最大值
        }
        if (width<=0){
            width=displayMetrics.widthPixels;
        }
        //int height = lp.height == ViewGroup.LayoutParams.WRAP_CONTENT ? 0 : imageView.getHeight();
        int height = imageView.getHeight();//擷取imageview的實際高度

        if (height <=0){
            height=lp.height;//擷取imageview再layout聲明的高度
        }
        if (height<=0){
            height=getImageViewFieldValue(imageView,"mMaxHeight");;//檢查最大值
        }
        if (height<=0){
            height=displayMetrics.heightPixels;
        }
        imageSize.width=width;
        imageSize.height=height;
        return imageSize;
    }

    /**
     * 通過反射獲得imageView的某個屬性值
     * @return
     */
    private  static  int getImageViewFieldValue(Object object,String fieldName){
        int value=0;

        try {
            Field field=ImageView.class.getDeclaredField(fieldName);
            field.setAccessible(true);
            int fieldValue = field.getInt(object);
            if (fieldValue>0&&fieldValue<Integer.MAX_VALUE){
                value=fieldValue;
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return  value;
    }
    private  synchronized void addTask(Runnable runnable)  {
        mTaskQueue.add(runnable);
        try {
            if (mPoolThreadHandler==null){
                mSemaphorePoolThreadHandler.acquire();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        mPoolThreadHandler.sendEmptyMessage(0x110);
    }

    /**
     * 根據path為imageview設定圖檔
     * @param key
     * @return
     */
    private Bitmap getBitmapFromLruCache(String key) {
         return mLruCache.get(key);
    }
   private  class  ImageSize{
       int width;
       int height;
   }
    private class ImgBeanHolder{
        Bitmap bitmap;
        ImageView imageView;
        String path;
    }
}      

2.圖檔的清單

首先掃描手機上的所有圖檔資訊,拿到圖檔數量最多的檔案夾,直接顯示在GridView上;并且掃描結束,得到一個所有包含圖檔的檔案夾資訊的List;

對于檔案夾資訊,我們單獨建立了一個Bean: 

public class FolderBean {
    private String dir;//目前檔案夾路徑
    private String firstImamgPath;//第一張圖檔的路徑
    private String name;//檔案夾的名字
    private int count; //圖檔數量

    public String getDir() {
        return dir;
    }

    public void setDir(String dir) {
        this.dir = dir;
        int indexOf = this.dir.lastIndexOf("/")+1;
        this.name=this.dir.substring(indexOf);
    }

    public String getFirstImamgPath() {
        return firstImamgPath;
    }

    public void setFirstImamgPath(String firstImamgPath) {
        this.firstImamgPath = firstImamgPath;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }
}      

其次是掃描手機中的圖檔:

注意:在6.0系統以上,要手動開啟讀取記憶體卡的權限,否則程式是運作不起來的。

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
    if (ContextCompat.checkSelfPermission(SelectPhotoActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(SelectPhotoActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
    }else{
        aboutScanPhoto();//未開啟權限,先開啟權限。以開啟權限後,直接掃描圖檔
    }
}else{
    aboutScanPhoto();//掃描圖檔的方法
}      
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode){
        case 1:
            if(grantResults.length>0 &&grantResults[0] == PackageManager.PERMISSION_GRANTED){
                aboutScanPhoto();
            }else {
                Toast.makeText(this, "請打開權限!", Toast.LENGTH_SHORT).show();
            }
            break;
        default:
    }
}      

掃描圖檔的方法

if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    Toast.makeText(this,"目前存儲卡不可用!",Toast.LENGTH_LONG);
    return;
}
mProgressDialog= ProgressDialog.show(this,null,"正在加載。。。");
new Thread(){
    @Override
    public void run() {
        Uri mImgUri= MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        ContentResolver cr=SelectPhotoActivity.this.getContentResolver();
        Cursor mCursor = cr.query(mImgUri, null,
                MediaStore.Images.Media.MIME_TYPE + "=? or "
                        + MediaStore.Images.Media.MIME_TYPE + "=?",
                new String[] { "image/jpeg", "image/png" },
                MediaStore.Images.Media.DATE_MODIFIED);
        Set<String> mDirPaths=new HashSet<String>();
        while (mCursor.moveToNext()){
            String path = mCursor.getString(mCursor.getColumnIndex(MediaStore.Images.Media.DATA));
            File parentFile=new File(path).getParentFile();
            if (parentFile==null) {
                continue;
            }
            String dirPath = parentFile.getAbsolutePath();
            FolderBean folderBean=null;
            if (mDirPaths.contains(dirPath)){
                continue;
            }else{
                mDirPaths.add(dirPath);
                folderBean=new FolderBean();
                folderBean.setDir(dirPath);
                folderBean.setFirstImamgPath(path);
            }

            if (parentFile.list()==null){
                continue;
            }
            int picSize=parentFile.list(new FilenameFilter() {
                @Override
                public boolean accept(File dir, String name) {
                    if (name.endsWith(".jpg")||name.endsWith("jpeg")||name.endsWith("png")){
                        return  true;
                    }
                    return false;
                }
            }).length;
            folderBean.setCount(picSize);
            mFolderBeans.add(folderBean);

            if (picSize>mMaxCount){
                mMaxCount=picSize;
                mCurrentDir=parentFile;
            }
        }
        mCursor.close();
        handler.sendEmptyMessage(0x110);

    }
}.start();      

然後我們通過handler發送消息,在handleMessage裡面:

1、建立GridView的擴充卡,為我們的GridView設定擴充卡,顯示圖檔;

2、建立我們的popupWindow了

private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        if (msg.what==0x110){
            mProgressDialog.dismiss();
            dataToView();
            initPopupWindow();
        }
    }
};      

dataToView()就是我們為view設定資料

private void dataToView() {
    if (mCurrentDir==null){
        Toast.makeText(this,"未掃描到任何圖檔",Toast.LENGTH_LONG).show();
        return;
    }
    mImgs= Arrays.asList(mCurrentDir.list());
    adapter = new ImageAdapter(this,mImgs,mCurrentDir.getAbsolutePath());
    mGridView.setAdapter(adapter);
    mTvDirName.setText(mCurrentDir.getName());
    mTvDirCount.setText(mMaxCount+"");
}      

我們還用到了一個GridView的adapter

public  class ImageAdapter extends BaseAdapter {
    private  String mDirPath;
    private List<String> mImgPaths;
    private LayoutInflater mInflater;
    private static List<String> mSelectImg=new LinkedList<>();
    public ImageAdapter(Context context, List<String> mDatas, String dirPath) {
        this.mDirPath=dirPath;
        this.mImgPaths=mDatas;
        mInflater=LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return mImgPaths.size();
    }

    @Override
    public Object getItem(int position) {
        return mImgPaths.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder vh=null;
        if (convertView==null){
            convertView=  mInflater.inflate(R.layout.item,parent,false);
            vh=new ViewHolder();
            vh.mImg=convertView.findViewById(R.id.iv_item);
            vh.mSelect=convertView.findViewById(R.id.ib_select);
            convertView.setTag(vh);
        }else {
            vh = (ViewHolder) convertView.getTag();
        }
        vh.mImg.setImageResource(R.mipmap.default_error);
        vh.mSelect.setImageResource(R.mipmap.btn_unselected);
        vh.mImg.setColorFilter(null);
        final String filePath=mDirPath+"/"+mImgPaths.get(position);
        //   new  ImageLoader(3, ImageLoader.Type.LIFO).loadImage(mDirPath + "/" + mImgPaths.get(position),vh.mImg);
        ImageLoader.getInStance(3, ImageLoader.Type.LIFO).loadImage(mDirPath+"/"+mImgPaths.get(position),vh.mImg);
        final ViewHolder finalVh = vh;
        vh.mImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //已經被選擇
                if (mSelectImg.contains(filePath)){
                    mSelectImg.remove(filePath);
                    finalVh.mImg.setColorFilter(null);
                    finalVh.mSelect.setImageResource(R.mipmap.btn_unselected);
                }else{
                    //未被選中
                    mSelectImg.add(filePath);
                    finalVh.mImg.setColorFilter(Color.parseColor("#77000000"));
                    finalVh.mSelect.setImageResource(R.mipmap.btn_selected);
                }

            }
        });
        if (mSelectImg.contains(filePath)){
            vh.mImg.setColorFilter(Color.parseColor("#77000000"));
            vh.mSelect.setImageResource(R.mipmap.btn_selected);
        }
        return convertView;
    }



    public List<String> selectPhoto(){
        if (!mSelectImg.isEmpty()){
            return mSelectImg;
        }
        return null;
    }
    private  class  ViewHolder{
        ImageView mImg;
        ImageButton mSelect;
    }
}      

3.到這一步圖檔就已經顯示在GridView中,下一步就是我們的popupWindow

要實作的效果是:點選底部的布局彈出我們的檔案夾選擇框,并且我們彈出框後面的Activity要變暗;

首先我們建立了一個popupWindow使用的類,和Activity類似:

public class ListImageDirPopupWindow extends PopupWindow {
    private  int mWidth;
    private int mHeight;
    private View mConvertView;
    private List<FolderBean> mDatas;
    private ListView mListView;

    public  interface  OnDirSelectedListener{
        void onSelected(FolderBean folderBean);
    }
    public  OnDirSelectedListener mListener;

    public void setOnDirSelectedListener(OnDirSelectedListener mListener) {
        this.mListener = mListener;
    }

    public ListImageDirPopupWindow(Context context, List<FolderBean> datas) {
       calWidthAndHeight(context);
        mConvertView= LayoutInflater.from(context).inflate(R.layout.popup_main,null);
        mDatas=datas;
        setContentView(mConvertView);
        setWidth(mWidth);
        setHeight(mHeight);
        setFocusable(true);
        setTouchable(true);
        setOutsideTouchable(true);
        setBackgroundDrawable(new BitmapDrawable());

        setTouchInterceptor(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if (event.getAction()==MotionEvent.ACTION_OUTSIDE){
                    dismiss();
                    return true;
                }
                return false;
            }
        });
        initViews(context);
        initEvent();
    }

    private void initViews(Context context) {
        mListView=  mConvertView.findViewById(R.id.lv_dir);
        mListView.setAdapter(new ListDirAdapter(context,mDatas));
    }

    private void initEvent() {
       mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
           @Override
           public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               if (mListener!=null){
                   mListener.onSelected(mDatas.get(position));
               }
           }
       });
    }

    /**
     * 計算popupWindow的寬度和高度
     * @param context
     */
    private void calWidthAndHeight(Context context) {

        WindowManager wm= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics=new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        mWidth= outMetrics.widthPixels;
        mHeight= (int) (outMetrics.heightPixels*0.7);

    }
    private class  ListDirAdapter extends ArrayAdapter<FolderBean>{

        private  LayoutInflater mInflater;
        private  List<FolderBean> mDatas;

        public ListDirAdapter(@NonNull Context context, List<FolderBean> datas) {
            super(context, 0, datas);
            mInflater= LayoutInflater.from(context);
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            ViewHolder vh=null;
            if (convertView==null){
                vh=new ViewHolder();
                convertView=  mInflater.inflate(R.layout.popup_item,parent,false);
                vh.mDirName=(TextView) convertView.findViewById(R.id.tv_dir_item_name);
                vh.mDirCount=(TextView) convertView.findViewById(R.id.tv_dir_item_count);
                vh.mImg= (ImageView) convertView.findViewById(R.id.iv_dir_image);
                convertView.setTag(vh);
            }else{
                vh= (ViewHolder) convertView.getTag();
            }
            FolderBean bean = getItem(position);
            //重置
            vh.mImg.setImageResource(R.mipmap.default_error);

            ImageLoader.getInStance(3, ImageLoader.Type.LIFO).loadImage(bean.getFirstImamgPath(),vh.mImg);
            vh.mDirName.setText(bean.getName());
            vh.mDirCount.setText(bean.getCount()+"");
            return convertView;
        }

        private  class  ViewHolder{
            ImageView mImg;
            TextView mDirName;
            TextView mDirCount;
        }
    }
}      

然後我們需要和Activity互動,當我們點選某個檔案夾的時候,外層的Activity需要改變它GridView的資料源,展示我們點選檔案夾的圖檔。在這裡我們建立一個接口OnDirSelectedListener ,對Activity設定回調;

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        if (mListener!=null){
            mListener.onSelected(mDatas.get(position));
        }
    }
});      

4.選擇不同的檔案夾

前面我們handleMessage中初始化調用popupWindow,通過activity的回調,實作選擇檔案夾顯示圖檔

mImageDirPopupWindow=new ListImageDirPopupWindow(this,mFolderBeans);
mImageDirPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
    @Override
    public void onDismiss() {
        lightOn();
    }
});
mImageDirPopupWindow.setOnDirSelectedListener(new ListImageDirPopupWindow.OnDirSelectedListener() {
    @Override
    public void onSelected(FolderBean folderBean) {
        mCurrentDir=new File(folderBean.getDir());
       mImgs= Arrays.asList(mCurrentDir.list(new FilenameFilter() {
            @Override
            public boolean accept(File dir, String name) {
                if (name.endsWith(".jpg")||name.endsWith("jpeg")||name.endsWith("png")){
                    return  true;
                }
                return false;
            }
        }));
        adapter=new ImageAdapter(SelectPhotoActivity.this,mImgs,mCurrentDir.getAbsolutePath());
        mGridView.setAdapter(adapter);
        mTvDirCount.setText(mImgs.size()+"");
        mTvDirName.setText(folderBean.getName());
        mImageDirPopupWindow.dismiss();
    }
});      

5.圖檔展示在RecyclerView中

在ImageAdapter中定義了一個方法,獲得選擇圖檔的路徑,點選“選擇”按鈕的時候,把這個路徑的集合傳過去

public List<String> selectPhoto(){
    if (!mSelectImg.isEmpty()){
        return mSelectImg;
    }
    return null;
}      

然後通過ImageLoader這個類将圖檔展示出來,我們在recyclerview設定圖檔展示方式為網格方式。

ImageLoader.getInStance(3, ImageLoader.Type.LIFO).loadImage(mDatas.get(position),holder.iv);      
if (photoSelect!=null) {
    final SimpleAdapter mAdapter = new SimpleAdapter(this, photoSelect);
    mListView.setAdapter(mAdapter);
    mListView.setLayoutManager(new GridLayoutManager(this,3));
}      

其中涉及到了一個adapter,是recyclerview所需要的

public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.MyViewHolder> {

    private LayoutInflater mInflater;
    private Context mContext;
    protected List<String> mDatas;

    public SimpleAdapter(Context mContext, List<String> mDatas) {
        this.mContext = mContext;
        this.mDatas = mDatas;
        mInflater=LayoutInflater.from(mContext);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.list_item, parent, false);
        MyViewHolder viewHolder=new MyViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        ImageLoader.getInStance(3, ImageLoader.Type.LIFO).loadImage(mDatas.get(position),holder.iv);
    }

    @Override
    public int getItemCount() {
        return mDatas.size();
    }

    class  MyViewHolder extends RecyclerView.ViewHolder {
        ImageView iv;
        public MyViewHolder(View itemView) {
            super(itemView);
            iv=  itemView.findViewById(R.id.iv_photo);
        }
    }
}      

如果大家想學習RecyclerView的使用,可以看一下我的部落格

https://blog.csdn.net/wen_haha/article/details/80775056

總結:本項目的主要代碼基本已經貼出來了,感興趣的朋友可以去下載下傳本人的項目,最後,如有不對的地方,請多多指教.

Demo

CSDN位址:

https://download.csdn.net/download/wen_haha/10499827

Github位址:

https://github.com/kongkongdaren/SelectPhotoDemo