RecyclerView+ImageLoader打造多選圖庫,recyclerview多選

來源:互聯網
上載者:User

RecyclerView+ImageLoader打造多選圖庫,recyclerview多選

在上一篇部落格《Universal-ImageLoader源碼解析》中,我們從源碼的角度分析了ImageLoader,這篇部落格我們就開始結合RecyclerView和ImageLoader打造一個圖片系統。

需求

在我的項目中有一個多圖選擇的需求,但是系統的圖庫只能選擇一張圖片,所以我們只能自己來做一個簡單的圖片。利用RecyclerView和ImageLoader可以很輕鬆的實現這個功能,下面我們先來看看效果吧。

Activity的實現

activity的實現很簡單,我們先來看看代碼,

public class GalleryActivity extends BaseActivity {    private RecyclerView mRecyclerView;    private GridLayoutManager mLayoutManager;    private ArrayList<GalleryImage> mImages; // 所有圖片    private ImageGalleryAdapter mAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.gallery_layout);        setupViews();        // 擷取圖片        new OpusBiz().getImages(new OnImagesListener() {            @Override            public void onResult(ArrayList<GalleryImage> images) {                if(images == null || images.isEmpty()) return;                mImages = images;                setAdapter();            }        });    }    @Override    protected void setupViews() {        super.setupViews();        setNormalTitle(R.string.select_image_text);        mTitleBar.setRightText(R.string.ok);        mRecyclerView = (RecyclerView) findViewById(R.id.rv_gallery);        mLayoutManager = new GridLayoutManager(this, 4, GridLayoutManager.HORIZONTAL, false);        mRecyclerView.setLayoutManager(mLayoutManager);        mRecyclerView.setItemAnimator(new DefaultItemAnimator());    }    private void setAdapter() {        mAdapter = new ImageGalleryAdapter(mRecyclerView, mImages);        mRecyclerView.setAdapter(mAdapter);    }    @Override    protected void onRightClick() {        ArrayList<GalleryImage> images = mAdapter.getSelected();        Intent intent = getIntent();        intent.putExtra(Constants.EXTRA_GALLERY_IMAGE, images);        setResult(RESULT_OK, intent);        onLeftClick();    }}

首先我們看看setupViews,這裡面find了RecyclerView,並且給他設定了一個GridLayoutManager,這樣我們的RecyclerView顯示出來就是一個網格的布局了,是不是很簡單!new OpusBiz().getImages()是從通過系統資料庫擷取圖片並回調,這裡面的代碼我們稍後再看,最後我們new了一個ImageGalleryAdapter,並且將這個Adapter設定給了RecyclerView。

接下來我們看看怎麼擷取的圖片吧。

圖片的擷取
public class OpusBiz {    /**     * 從系統資料庫中擷取圖庫圖片     * @param li     */    public void getImages(final OnImagesListener li) {        final Handler handler = new Handler() {            @Override            public void handleMessage(Message msg) {                if(msg.what == Constants.MSG_SUCCESS)                    li.onResult((ArrayList<GalleryImage>) msg.obj);            }        };        new Thread(new Runnable() {            @Override            public void run() {                handler.obtainMessage(Constants.MSG_SUCCESS, getImages()).sendToTarget();            }        }).start();    }    /**     * 從系統資料庫中擷取圖庫圖片     * @return     */    private ArrayList<GalleryImage> getImages() {        ArrayList<GalleryImage> images = new ArrayList<GalleryImage>();        GalleryImage image;        final String[] columns = { MediaStore.Images.Media.DATA,                MediaStore.Images.Media._ID };        final String orderBy = MediaStore.Images.Media.DATE_TAKEN;        Cursor imagecursor = App.getInstance().getContentResolver()                .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,                        null, null, orderBy + " DESC");        for (int i = 0; i < imagecursor.getCount(); i++) {            imagecursor.moveToPosition(i);            int dataColumnIndex = imagecursor                    .getColumnIndex(MediaStore.Images.Media.DATA);            image = new GalleryImage();            image.setUri(imagecursor.getString(dataColumnIndex));            images.add(image);        }        return images;    }    /**     * 擷取圖庫圖片     */    public interface OnImagesListener {        public void onResult(ArrayList<GalleryImage> images);    }}

這裡面開啟了一個線程去查詢系統資料庫,擷取圖片的路徑,然後然後一個ArrayList中,最後回調。
接下來我們繼續看看Adapter怎麼寫的

ImageGalleryAdapter
public class ImageGalleryAdapter extends    RecyclerView.Adapter<ImageGalleryAdapter.ImageViewHolder> {    private RecyclerView mRecyclerView;    private ArrayList<GalleryImage> mImages;    private ArrayList<GalleryImage> mSelected;    public ImageGalleryAdapter(RecyclerView recyclerView, ArrayList<GalleryImage> images) {        mRecyclerView = recyclerView;        mImages = images;        mSelected = new ArrayList<GalleryImage>(UploadOpusActivity.MAX_COUNT);    }    public ArrayList<GalleryImage> getSelected() {        return mSelected;    }    @Override    public int getItemCount() {        return mImages.size();    }    @Override    public void onBindViewHolder(final ImageViewHolder holder, int position) {        final GalleryImage image = mImages.get(holder.getLayoutPosition());        String uri = image.getUri();        if(!uri.startsWith("file://")) uri = "file://" + image.getUri();        ImageLoaderUtils.getInstance().displayImage(uri, holder.image);        holder.item.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                boolean isChecked = !image.isChecked();                // 如果是選擇狀態                if(isChecked) {                    // 則需要判斷當前選擇了幾個                    if(mSelected.size() >= UploadOpusActivity.MAX_COUNT) return;                    // 添加到選擇的列表中                    mSelected.add(image);                }else {                    // 取消選擇                    mSelected.remove(image);                }                // 純粹為了顯示                holder.cb.setChecked(isChecked);                image.setChecked(isChecked);            }        });        holder.cb.setChecked(image.isChecked());    }    @Override    public ImageViewHolder onCreateViewHolder(ViewGroup parent, int position) {        View view = LayoutInflater.from(parent.getContext())                .inflate(R.layout.gallery_item, parent, false);        return new ImageViewHolder(view);    }    class ImageViewHolder extends RecyclerView.ViewHolder {        View item;        ImageView image;        CheckBox cb;        public ImageViewHolder(View view) {            super(view);            item = view;            image = (ImageView) view.findViewById(R.id.iv_gallery_item_image);            cb = (CheckBox) view.findViewById(R.id.cb_gallery_item_check);            int size = mRecyclerView.getMeasuredHeight() / 4;            LayoutParams p = image.getLayoutParams();            p.width = size;            p.height = size;        }    }}

也是一個簡單的RecyclerView的adapter,主要看onBindViewHolder裡的代碼,

ImageLoaderUtils.getInstance().displayImage(uri, holder.image);holder.item.setOnClickListener(new OnClickListener() {  @Override  public void onClick(View v) {    boolean isChecked = !image.isChecked();    // 如果是選擇狀態    if(isChecked) {      // 則需要判斷當前選擇了幾個      if(mSelected.size() >= UploadOpusActivity.MAX_COUNT) return;      // 添加到選擇的列表中      mSelected.add(image);    }else {      // 取消選擇      mSelected.remove(image);    }    // 純粹為了顯示    holder.cb.setChecked(isChecked);    image.setChecked(isChecked);  }});holder.cb.setChecked(image.isChecked());

首先通過ImageLoader載入了圖片,然後監聽了整個item的點擊事件,如果是將要去選擇,我們需要判斷選擇的最大數,如果大於我們允許的最大選擇數則直接返回,否則,將選擇的圖片放到選擇類別中,如果當前是選擇狀態,則就是要去取消選擇,直接從挑選清單中移除。最後,我們改變了CheckBox的選擇狀態。
最後的最後,附上對ImageLoader封裝的代碼,

public class ImageLoaderUtils {    private static ImageLoaderUtils sInstance;    private DisplayImageOptions mOptions;    public synchronized static ImageLoaderUtils getInstance() {        if(sInstance == null) sInstance = new ImageLoaderUtils();        return sInstance;    }    private ImageLoaderUtils() {        setDefault();    }    private void setDefault() {        mOptions = new DisplayImageOptions.Builder()        .showImageOnLoading(R.drawable.default_icon)        .showImageForEmptyUri(R.drawable.default_icon)        .showImageOnFail(R.drawable.default_icon)        .cacheInMemory(true)        .cacheOnDisk(true)        .bitmapConfig(Config.RGB_565) // 2倍圖        .considerExifParams(true)        .displayer(new SimpleBitmapDisplayer()).build();    }    /**     * 設定預設的表徵圖     * @param res     * @return     */    public ImageLoaderUtils defaultIcon(int res) {        mOptions = new DisplayImageOptions.Builder()        .showImageOnLoading(res)        .showImageForEmptyUri(res)        .showImageOnFail(res)        .cacheInMemory(true)        .cacheOnDisk(true)        .bitmapConfig(Config.RGB_565) // 2倍圖        .considerExifParams(true)        .displayer(new SimpleBitmapDisplayer()).build();        return sInstance;    }    /**     * 擷取圖片     * @param url 圖片url     * @param l 回調     */    public void loadImage(final String url, final ImageLoaderListener l) {        ImageLoader.getInstance().loadImage(url, mOptions, l);    }    /**     * 顯示圓形圖片     * @param uri     * @param imageView     * @param radius  半徑     */    public void displayRoundImage(String uri, ImageView imageView, int radius) {        DisplayImageOptions options = new DisplayImageOptions.Builder()        .showImageOnLoading(R.drawable.default_icon)        .showImageForEmptyUri(R.drawable.default_icon)        .showImageOnFail(R.drawable.default_icon)        .cacheInMemory(true)        .cacheOnDisk(true)        .considerExifParams(true)        .bitmapConfig(Config.RGB_565) // 2倍圖        .displayer(new RoundedBitmapDisplayer(radius)).build();        displayImage(uri, imageView, options);    }    public void displayImage(String uri, ImageView imageView) {        displayImage(uri, imageView, mOptions);//      ImageLoader.getInstance().displayImage(uri, imageView, mOptions);        setDefault(); // 恢複預設    }    private void displayImage(String uri, ImageView imageView, DisplayImageOptions options) {        if(uri == null) return;        ImageLoader.getInstance().displayImage(uri, imageView, options);    }    public static abstract class ImageLoaderListener implements ImageLoadingListener {        @Override        public void onLoadingStarted(String imageUri, View view) {        }        @Override        public void onLoadingFailed(String imageUri, View view,                FailReason failReason) {        }        @Override        public void onLoadingCancelled(String imageUri, View view) {        }    }}

整體代碼非常簡單,實現了一個可多選圖片的圖庫功能。

著作權聲明:本文來自Loader's Blog,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.