当前位置: 首页 > news >正文

图片选择器ImageEditContainer

 

1. 简介

本次demo中一共封装了两个组件:ImageEditButton 和 ImageEditContainer。其中ImageEditContainer 是在 ImageEditButton,两个组件可单独使用。

在demo中,实现了 图片选择(拍照+本地),裁剪,压缩,保存本地 以及对已选择图片的删除操作(如果有修改需求,也可以使用对应方法进行操作,该方法已添加);

 还有就是 针对 6.0权限的处理问题,本次使用了第三方库 rxpermissions 进行权限的处理。

2.项目主目录结构

 

3. 功能介绍

MainActivity.java 界面效果图:

 

 

ImageEditContainer 组件初始化:
        layImageContainer = (ImageEditContainer) findViewById(R.id.lay_image_container);
        layImageContainer.setEditListener(this);
        layImageContainer.setBtnImageResource(R.drawable.icon_picture_photograph);
        layImageContainer.setTotalImageQuantity(3);

如上代码,设置组件的监听,添加按钮展示图,以及最多选择图片个数。

implements  ImageEditContainer.ImageEditContainerListener 的实现
@Override
    public void doAddImage() {
        PopupWindow mCameraPop = SelectPicturePopupWindowUtils.showSelectPicturePopupWindow(this);
        if (mCameraPop != null)
            mCameraPop.showAtLocation(layImageContainer, Gravity.BOTTOM, 0, 0);
    }

    @Override
    public void doEditLocalImage(ImageItem imageItem) {
        if (imageItem != null) {
            layImageContainer.updateEditedImageItem(imageItem);
        }
    }

    @Override
    public void doEditRemoteImage(RemoteImageItem remoteImageItem) {
        if (remoteImageItem != null) {
            if (remoteImageItem.isDeleted) {
                layImageContainer.removeRemoteImageItem(remoteImageItem);
            } else {
                layImageContainer.updateRemoteImageItem(remoteImageItem);
            }
        }
    }

  

当图片选择数量达到最大个数时,添加按钮会消失。效果图如下所示:

 

图片裁剪 效果图如下所示:

图片可拖拽,缩放


图片选择好后,进行图片压缩:
    private void compressImage(String path) {

        if (TextUtils.isEmpty(path)) {
            return;
        }
        compressImage = compressImage + 1;
        ImageItem imageItem = new ImageItem();
        imageItem.storedPath = path;

        File file = new File(FilePathUtils.getImageSavePath());
        if (!file.exists()) {
            file.mkdirs();
        }
        String filePath = FilePathUtils.getImageSavePath() + System.currentTimeMillis() + ".jpg";
        new Thread(new MyThread(imageItem, path, filePath)).start();
        List<String> imagePaths = new ArrayList<>();
        imagePaths.add(path);
        layImageContainer.addNewImageItem(imageItem);
    }

图片压缩比较慢,要开启个 线程进行压缩:

public class MyThread implements Runnable {
        private String imgPath;
        private String outPath;
        private ImageItem imageItem;

        public MyThread(ImageItem imageItem, String imgPath, String outPath) {
            this.imageItem = imageItem;
            this.imgPath = imgPath;
            this.outPath = outPath;
        }

        public void run() {
            try {
                BitmapUtil.compressAndGenImage(imgPath, outPath, 500, false);
                compressImage = compressImage - 1;
                imageItem.storedPath = outPath;
            } catch (IOException e) {
                compressImage = compressImage - 1;
                e.printStackTrace();
            }
        }
    }

使用的压缩方法:

    /**
     * Compress by quality,  and generate image to the path specified
     *
     * @param imgPath
     * @param outPath
     * @param maxSize     target will be compressed to be smaller than this size.(kb)
     * @param needsDelete Whether delete original file after compress
     * @throws IOException
     */
    public static void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {
        compressAndGenImage(getBitmap(imgPath), outPath, maxSize);

        // Delete original file
        if (needsDelete) {
            File file = new File(imgPath);
            if (file.exists()) {
                file.delete();
            }
        }
    }

 

组件 ImageEditContainer 添加图片方法介绍:

可添加本地和网络图片

    /**
     * 添加本地图片 
     * List<String> storePaths 本地图片路径数组
     */
    public void addNewImages(List<String> storePaths) {


    }


    /**
     * 添加本地图片
     */
    public void addNewImageItem(ImageItem imageItem) {

    }

    /**
     * 添加网络图片
     */
    public void addRemoteImageItem(RemoteImageItem remoteImageItem) {

    }

 

组件 ImageEditContainer 其他方法介绍:

   /**
     * 设置组件中 选择按钮的宽高
     */
public void setImvHeightAndWidth(int height, int width) {

    }
  /**
     * 设置图片最大数量
     */
    public void setTotalImageQuantity(int totalImageQuantity) {

    }
/**
     * 设置图片展示图
     */
    public void setBtnImageResource(int resid) {

    }
  /**
     * 获取组件中所有图片对象(本地+网络)
     */
    public List<Object> getAllImageItems() {

    }

  public void updateEditedImageItem(ImageItem imageItem) {
      
    }

  /**
     * 更新网络图片
     */
    public void updateRemoteImageItem(RemoteImageItem remoteImageItem) {
}

  /**
     * 删除网络图片
     */
    public void removeRemoteImageItem(RemoteImageItem remoteImageItem) {
}

 

4. 组件代码

1.ImageEditButton.java 

/**
 * Created by dingzuoqiang on 2017/6/20.
 * Email: 530858106@qq.com
 */
public class ImageEditButton extends RelativeLayout {

    private final static String TAG = "ImageEditButton";

    private ImageView imvAddImage;
    private ImageView imvEdit;

    private int imvHeight;
    private int imvWidth;
    public ImageEditButtonListener editButtonListener;

    public ImageEditButton(Context context) {
        this(context, null);
    }


    public ImageEditButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.image_edit_button_view, this, true);
        imvHeight = CommonUtil.dip2px(getContext(), 70);
        imvWidth = imvHeight;
        imvAddImage = (ImageView) findViewById(R.id.imv_add_image);
        imvEdit = (ImageView) findViewById(R.id.imv_edit);
        setImvHeightAndWidth(imvHeight, imvWidth);
        imvAddImage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                doEditImage();
            }
        });
        imvEdit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                doEditImage2();
            }
        });
    }

    public void setImvHeightAndWidth(int height, int width) {
        this.imvHeight = height;
        this.imvWidth = width;
        ViewGroup.LayoutParams layoutParams = imvAddImage.getLayoutParams();
        layoutParams.width = imvHeight;
        layoutParams.height = imvWidth;
        imvAddImage.setLayoutParams(layoutParams);
    }

    public int getImvHeight() {
        return imvHeight;
    }

    public int getImvWidth() {
        return imvWidth;
    }

    public void setPadding2(int left, int top, int right, int bottom) {
        this.setPadding(left, top, right, bottom);
    }

    public void setBtnImageResource(int resid) {
        imvAddImage.setImageResource(resid);
//        ImageLoaderUtils.loadImageFromDrawable(resid, imvAddImage, null);
    }

    public void reset() {
        imvEdit.setVisibility(GONE);
    }

    public void setEditButtonListener(ImageEditButtonListener editButtonListener) {
        this.editButtonListener = editButtonListener;
    }

    public BaseImageItem getImageItem() {
        Object object = this.getTag();
        if (object instanceof BaseImageItem) return (BaseImageItem) object;
        return null;
    }

    public void displayUI() {
        //
        Object object = this.getTag();
        if (object == null) return;
        if (object instanceof ImageItem) {
            ImageItem imageItem = (ImageItem) object;

            if (TextUtils.isEmpty(imageItem.storedPath))
                return;
            File file = new File(imageItem.storedPath);
            if (file.exists()) {
//                其实Glide加载本地图片和加载网络图片调用的方法是一样的,唯一的区别是说加载SD卡的图片需要SD卡的权限,加载网络需要网络权限
                Glide.with(getContext()).load(file).crossFade().into(imvAddImage);
            }
        } else if (object instanceof RemoteImageItem) {
            // 如果是 remoteImageItem 则需要从读取图片,同时不可以裁剪
            RemoteImageItem remoteImageItem = (RemoteImageItem) object;
            Glide.with(getContext()).load(remoteImageItem.thumbUrl).centerCrop().crossFade().into(imvAddImage);
        }

        // TODO
        BaseImageItem baseImageItem = (BaseImageItem) object;
        displayNoteIcons(baseImageItem);
    }

    private void displayNoteIcons(BaseImageItem baseImageItem) {
        imvEdit.setVisibility(VISIBLE);
    }

    private void doEditImage() {
        if (editButtonListener == null) return;

        Object object = this.getTag();
        if (object == null) {
            // add image
            editButtonListener.doAddImage();
        } else {
            //
            if (object instanceof ImageItem) {
                editButtonListener.doEditLocalImage((ImageItem) object);
            } else if (object instanceof RemoteImageItem) {
                editButtonListener.doEditRemoteImage((RemoteImageItem) object);
            }
        }


    }

    private void doEditImage2() {
        if (editButtonListener == null) return;

        Object object = this.getTag();
        if (object != null) {
            //
            if (object instanceof ImageItem) {
                ImageItem imageItem = (ImageItem) object;
                imageItem.isDeleted = true;
                editButtonListener.doEditLocalImage(imageItem);
            } else if (object instanceof RemoteImageItem) {
                RemoteImageItem remoteImageItem = (RemoteImageItem) object;
                remoteImageItem.isDeleted = true;
                editButtonListener.doEditRemoteImage(remoteImageItem);
            }
        }


    }


    public interface ImageEditButtonListener {

        public void doAddImage();

        public void doEditLocalImage(ImageItem imageItem1);

        public void doEditRemoteImage(RemoteImageItem remoteImageItem);
    }


}

 

2.ImageEditContainer.java 

/**
 * Created by dingzuoqiang on 2017/6/20.
 * Email: 530858106@qq.com
 */
public class ImageEditContainer extends HorizontalScrollView implements ImageEditButton.ImageEditButtonListener {

    private final static String TAG = "ImageEditContainer";
    public ImageEditContainerListener mEditListener;
    private int idValue = 0;
    ImageEditButton imbAddImage;
    ViewGroup buttonsContainer;

    private int totalImageQuantity = 3;// 总添加数量
    private int mBtnBgResid = 0;

    public ImageEditContainer(Context context) {
        //super(context);
        this(context, null);
    }

    public ImageEditContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
        //
        LayoutInflater.from(context).inflate(R.layout.image_edit_container, this, true);

        imbAddImage = (ImageEditButton) findViewById(R.id.imb_add_image);
        imbAddImage.setEditButtonListener(this);
        //
        buttonsContainer = (ViewGroup) findViewById(R.id.lay_container);
        setHorizontalScrollBarEnabled(false);
        setHorizontalFadingEdgeEnabled(false);

    }

    public void setImvHeightAndWidth(int height, int width) {
        for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
            ImageEditButton imageEditButton = (ImageEditButton) buttonsContainer.getChildAt(i);
            if (imageEditButton == null) continue;
            imageEditButton.setImvHeightAndWidth(height, width);
        }
    }

    public void setTotalImageQuantity(int totalImageQuantity) {
        if (totalImageQuantity > 0)
            this.totalImageQuantity = totalImageQuantity;
    }

    public void setBtnImageResource(int resid) {
        mBtnBgResid = resid;
        imbAddImage.setBtnImageResource(mBtnBgResid);
    }

    public List<Object> getAllImageItems() {
        List<Object> allItems = new ArrayList<>();
        for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
            ImageEditButton imageEditButton = (ImageEditButton) buttonsContainer.getChildAt(i);
            if (imageEditButton == null) continue;
            if (imageEditButton.getTag() == null) continue;
            allItems.add(imageEditButton.getTag());
        }
        return allItems;
    }

    /**
     * 添加本地图片
     */
    public void addNewImages(List<String> storePaths) {

        for (int i = 0; i < storePaths.size(); i++) {
            String path = storePaths.get(i);
            ImageItem imageItem = new ImageItem();
            imageItem.storedPath = path;
            imageItem.id = idValue++;
            Log.i(TAG, "index=" + i + "  id=" + imageItem.id);
            imageItem.index = (buttonsContainer.getChildCount() - 1);
            addBaseImageItemToContainer(imageItem);

        }
    }

    /**
     * 添加本地图片
     */
    public void addNewImageItem(ImageItem imageItem) {
        if (imageItem == null) return;
        imageItem.id = idValue++;
        imageItem.index = (buttonsContainer.getChildCount() - 1);
        addBaseImageItemToContainer(imageItem);
    }

    public void updateEditedImageItem(ImageItem imageItem) {
        ImageEditButton imageEditButton = getImageEditButtonForImageItemById(imageItem);
        if (imageEditButton == null) {
            return;
        }

        Object originObj = imageEditButton.getTag();
        if (!(originObj instanceof ImageItem)) {
            if (originObj instanceof RemoteImageItem) {
                RemoteImageItem remoteItem = (RemoteImageItem) originObj;
                if (remoteItem.index == imageItem.index) {
                    imageEditButton.setTag(imageItem);
                    imageEditButton.displayUI();
                    return;
                }
                reorderForImageItem(imageItem);
            }
            return;
        }

        ImageItem originImageItem = (ImageItem) originObj;
        if (imageItem.isDeleted) {
            removeButtonContainImageItem(imageItem);
            resetImageItemIndex();
            return;
        } else {

            if (originImageItem.index == imageItem.index) {
                imageEditButton.setTag(imageItem);
                imageEditButton.displayUI();
                return;
            }
            reorderForImageItem(imageItem);
        }
    }


    /**
     * 添加网络图片
     */
    public void addRemoteImageItem(RemoteImageItem remoteImageItem) {
        addBaseImageItemToContainer(remoteImageItem);
    }

    /**
     * 更新网络图片
     */
    public void updateRemoteImageItem(RemoteImageItem remoteImageItem) {

        ImageEditButton imageEditButton = getImageEditButtonForImageItemById(remoteImageItem);
        if (imageEditButton == null) {
            if (getAllImageItems().size() > 0) {
                List<Object> objectList = getAllImageItems();
                for (int i = 0; i < objectList.size(); i++) {
                    BaseImageItem baseImageItem = (BaseImageItem) objectList.get(i);
                    removeButtonContainImageItem(baseImageItem);
                }
                //
                objectList.add(0, remoteImageItem);

                for (int i = 0; i < objectList.size(); i++) {
                    addRemoteImageItem((RemoteImageItem) objectList.get(i));
                }
                //
            } else {
                addRemoteImageItem(remoteImageItem);
            }

            return;
        }
        BaseImageItem baseImageItem = (BaseImageItem) imageEditButton.getTag();
        if (baseImageItem instanceof ImageItem) return;
        RemoteImageItem originRemoteItem = (RemoteImageItem) baseImageItem;

        if (remoteImageItem.index == originRemoteItem.index) {
            // index 相同 只是update
            imageEditButton.setTag(remoteImageItem);
            imageEditButton.displayUI();
            return;
        }
        reorderForImageItem(remoteImageItem);
    }

    /**
     * 删除网络图片
     */
    public void removeRemoteImageItem(RemoteImageItem remoteImageItem) {

        ImageEditButton imageEditButton = getImageEditButtonForImageItemById(remoteImageItem);
        if (null != imageEditButton && null != imageEditButton.getTag()) {
            BaseImageItem baseImageItem = (BaseImageItem) imageEditButton.getTag();
            if (baseImageItem instanceof ImageItem) return;
            RemoteImageItem originRemoteItem = (RemoteImageItem) baseImageItem;
            removeButtonContainImageItem(remoteImageItem);
            resetImageItemIndex();
        }
    }


    private void reorderForImageItem(BaseImageItem imageItem) {
        removeButtonContainImageItem(imageItem);
        List<BaseImageItem> imageItems = new ArrayList<>();
        imageItems.add(imageItem);
        int count = buttonsContainer.getChildCount();
        for (int i = imageItem.index; i < count; i++) {
            ImageEditButton button = (ImageEditButton) buttonsContainer.getChildAt(i);
            if (button == null) continue;
            BaseImageItem imageItem1 = (BaseImageItem) button.getTag();
            if (imageItem1 == null) continue;
            imageItems.add(imageItem1);
        }
        for (int i = 0; i < imageItems.size(); i++) {
            BaseImageItem item = imageItems.get(i);
            removeButtonContainImageItem(item);
        }
        //
        for (int i = 0; i < imageItems.size(); i++) {
            addBaseImageItemToContainer(imageItems.get(i));
        }

    }

    private void resetImageItemIndex() {
        for (int i = 0; i < buttonsContainer.getChildCount(); i++) {

            try {
                ImageEditButton button = (ImageEditButton) buttonsContainer.getChildAt(i);
                if (button == null) continue;
                BaseImageItem imageItem = (BaseImageItem) button.getTag();
                if (imageItem == null) continue;
                imageItem.index = i;

            } catch (Exception ignored) {

            }
        }
    }


    private ImageEditButton getImageEditButtonForImageItemById(BaseImageItem imageItem) {
        for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
            ImageEditButton imageEditButton = (ImageEditButton) buttonsContainer.getChildAt(i);
            if (imageEditButton == null) continue;
            if (imageEditButton.getImageItem() == null) continue;
            BaseImageItem searchedImageItem = imageEditButton.getImageItem();
            if (imageItem.id.longValue() == searchedImageItem.id.longValue()) {
                return imageEditButton;
            }
        }
        return null;
    }


    /*
    删除一个 ImageItem
     */
    private void removeButtonContainImageItem(BaseImageItem imageItem) {

        ImageEditButton imageEditButton = getImageEditButtonForImageItemById(imageItem);
        if (imageEditButton == null) return;
        buttonsContainer.removeView(imageEditButton);
        resetImageItemIndex();
        imbAddImage.setVisibility(buttonsContainer.getChildCount() <= totalImageQuantity ? VISIBLE : GONE);
    }


    private void addBaseImageItemToContainer(BaseImageItem imageItem) {
        buttonsContainer.removeView(imbAddImage);

        ImageEditButton imageEditButton = new ImageEditButton(getContext());
        if (mBtnBgResid != 0)
            imageEditButton.setBtnImageResource(mBtnBgResid);
        imageEditButton.setTag(imageItem);
        imageEditButton.setEditButtonListener(this);
//        buttonsContainer.addView(imageEditButton, buttonsContainer.getChildCount(), new RelativeLayout.LayoutParams(nSize, imbAddImage.getHeight()));
        buttonsContainer.addView(imageEditButton, buttonsContainer.getChildCount());
        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) imageEditButton.getLayoutParams();
        layoutParams.rightMargin = CommonUtil.dip2px(getContext(), 5);
        imageEditButton.setLayoutParams(layoutParams);
        imageEditButton.setImvHeightAndWidth(imbAddImage.getImvHeight(), imbAddImage.getImvWidth());
        imageEditButton.displayUI();
        //
        buttonsContainer.addView(imbAddImage, buttonsContainer.getChildCount());
        //
        imbAddImage.setVisibility(buttonsContainer.getChildCount() <= totalImageQuantity ? VISIBLE : GONE);

        resetImageItemIndex();

    }

    /*
    ImageEditButton listener
     */

    public void doAddImage() {
        if (mEditListener != null) {
            mEditListener.doAddImage();
        }
    }

    public void doEditLocalImage(ImageItem imageItem) {
        if (mEditListener != null) {
            mEditListener.doEditLocalImage(imageItem);
        }

    }

    public void doEditRemoteImage(RemoteImageItem remoteImageItem) {
        if (mEditListener != null) {
            mEditListener.doEditRemoteImage(remoteImageItem);
        }

    }
    // -----


    public void setEditListener(ImageEditContainerListener editListener) {
        this.mEditListener = editListener;
    }

    //

    public interface ImageEditContainerListener {
        public void doAddImage();

        public void doEditLocalImage(ImageItem imageItem1);

        public void doEditRemoteImage(RemoteImageItem remoteImageItem);
    }

 

项目源码下载:

 

转载于:https://www.cnblogs.com/dingzq/p/7130317.html

相关文章:

  • ETL基本概念
  • python学习笔记5-python的函数
  • oracle物化视图(materialized view)
  • 绝世好题bzoj4300
  • 在存储过程中拥有role的权限(Authid Current_User)
  • 渐变维度(Slowly Changing Dimension)及其处理方法
  • 获取url值
  • 1.Angular框架-angular介绍与基本使用,MVC模式介绍
  • Oracle性能调优-优化排序操作
  • 鲜为人知的软件项目管理原则
  • 业界经典语录
  • 数据仓库设计的思考
  • ubuntu下安装Java并设置环境变量
  • arguments、this指针、call和apply、bind语法
  • ubuntu修改主机名
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 【Leetcode】104. 二叉树的最大深度
  • Android开源项目规范总结
  • css系列之关于字体的事
  • JavaScript标准库系列——Math对象和Date对象(二)
  • leetcode388. Longest Absolute File Path
  • node.js
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • Solarized Scheme
  • 对超线程几个不同角度的解释
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 极限编程 (Extreme Programming) - 发布计划 (Release Planning)
  • 简单易用的leetcode开发测试工具(npm)
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 码农张的Bug人生 - 见面之礼
  • 前嗅ForeSpider采集配置界面介绍
  • 使用 QuickBI 搭建酷炫可视化分析
  • 网络应用优化——时延与带宽
  • 小程序button引导用户授权
  • 新书推荐|Windows黑客编程技术详解
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 异步
  • Python 之网络式编程
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • ​力扣解法汇总1802. 有界数组中指定下标处的最大值
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • $NOIp2018$劝退记
  • ()、[]、{}、(())、[[]]命令替换
  • (BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等(1)
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (C语言版)链表(三)——实现双向链表创建、删除、插入、释放内存等简单操作...
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (MATLAB)第五章-矩阵运算
  • (NSDate) 时间 (time )比较
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (初研) Sentence-embedding fine-tune notebook
  • (二)学习JVM —— 垃圾回收机制
  • (一) storm的集群安装与配置