美文网首页
Android调用系统相机、本地相册上传图片(头像上传(裁剪)、

Android调用系统相机、本地相册上传图片(头像上传(裁剪)、

作者: 可以再长高10cm | 来源:发表于2017-12-28 17:11 被阅读2138次

    开发中基本上都会有头像上传的功能,有的app还需要多张图片同时上传,下面简单将头像上传以及多张图片上传功能整理一下。图片选择仿照微信选择图片的界面。【参考】 多图片选择器
    !!!推荐一个动态权限请求的框架: 动态权限申请
    下面先看一下想要实现的效果图:多张图片

    22222.png
    选择图片:
    33333.png
    头像上传:
    11111.png
    一、头像上传(单张图片上传,可设置图片裁剪的比例)

    1、选择图片前请求读写权限。

    //先请求权限,再进行操作
                    AndPermission.with(MainActivity.this)
                            .requestCode(300)
                            .permission(
                                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                    Manifest.permission.READ_EXTERNAL_STORAGE)
                            .callback(this)
                            .start();
    

    权限申请注解

    // 成功回调的方法,用注解即可,这里的300就是请求时的requestCode。
        @PermissionYes(300)
        private void getPermissionYes(List<String> grantedPermissions) {
            // TODO 申请权限成功。
            if(AndPermission.hasPermission(this,grantedPermissions)) {
                // TODO 执行拥有权限时的下一步。
                chooseImage();
            } else {
                // 使用AndPermission提供的默认设置dialog,用户点击确定后会打开App的设置页面让用户授权。
                AndPermission.defaultSettingDialog(this, 300).show();
                // 建议:自定义这个Dialog,提示具体需要开启什么权限,自定义Dialog具体实现上面有示例代码。
            }
        }
    
        @PermissionNo(300)
        private void getPermissionNo(List<String> deniedPermissions) {
            // TODO 申请权限失败。
            if(AndPermission.hasPermission(this,deniedPermissions)) {
                // TODO 执行拥有权限时的下一步。
            } else {
                // 使用AndPermission提供的默认设置dialog,用户点击确定后会打开App的设置页面让用户授权。
                AndPermission.defaultSettingDialog(this, 300).show();
                // 建议:自定义这个Dialog,提示具体需要开启什么权限,自定义Dialog具体实现上面有示例代码。
            }
        }
    

    2、初始化图片选择器,设置裁剪形状为正方形。

    private ImagePicker getImagePickerSquare() {//正方形
            ImagePicker imagePicker = ImagePicker.getInstance();
            imagePicker.setImageLoader(new GlideImageLoader());   //设置图片加载器
            imagePicker.setShowCamera(true);                      //显示拍照按钮
            imagePicker.setCrop(true);                            //允许裁剪(单选才有效)
            imagePicker.setSaveRectangle(true);                   //是否按矩形区域保存
            imagePicker.setMultiMode(false);                      //多选
            imagePicker.setStyle(CropImageView.Style.RECTANGLE);  //裁剪框的形状
            imagePicker.setFocusWidth(800);                       //裁剪框的宽度。单位像素(圆形自动取宽高最小值)
            imagePicker.setFocusHeight(800);                      //裁剪框的高度。单位像素(圆形自动取宽高最小值)
            imagePicker.setOutPutX(1000);                         //保存文件的宽度。单位像素
            imagePicker.setOutPutY(1000);                         //保存文件的高度。单位像素
            return imagePicker;
        }
    

    3、选择图片。chooseImage()

    private void chooseImage() {
            List<String> names = new ArrayList<>();
            names.add("拍照");
            names.add("从相册选择");
            showDialog(new PictureChooseDialog.SelectDialogListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    switch (position) {
                        case 0: // 直接调起相机
                            //打开选择,本次允许选择的数量
                            getImagePickerSquare().setSelectLimit(maxImgCount - selImageList.size());
                            Intent intent = new Intent(MainActivity.this, ImageGridActivity.class);
                            intent.putExtra(ImageGridActivity.EXTRAS_TAKE_PICKERS,true); // 是否是直接打开相机
                            startActivityForResult(intent, REQUEST_CODE_SELECT);
                            break;
                        case 1:
                            //打开选择,本次允许选择的数量
                            getImagePickerSquare().setSelectLimit(maxImgCount - selImageList.size());
                            Intent intent1 = new Intent(MainActivity.this, ImageGridActivity.class);
                            startActivityForResult(intent1, REQUEST_CODE_SELECT);
                            break;
                        default:
                            break;
                    }
                }
            }, names);
        }
    

    4、选择图片后的处理,onActivityResult()

    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == ImagePicker.RESULT_CODE_ITEMS) {
                //添加图片返回
                if (data != null && requestCode == REQUEST_CODE_SELECT) {
                    ArrayList<ImageItem> images = (ArrayList<ImageItem>) data.getSerializableExtra(ImagePicker.EXTRA_RESULT_ITEMS);
                    if (images != null){
                        ImageItem imageItem = images.get(0);
                        String newPathHead = imageItem.path;
                        updateMineMessage(newPathHead);
                    }
                }
            } else if (resultCode == ImagePicker.RESULT_CODE_BACK) {
                //预览图片返回
                if (data != null && requestCode == REQUEST_CODE_PREVIEW) {
                    ArrayList<ImageItem> images = (ArrayList<ImageItem>) data.getSerializableExtra(ImagePicker.EXTRA_IMAGE_ITEMS);
                    if (images != null){
                        ImageItem imageItem = images.get(0);
    //                    String newPathHead = BitmapUtils.compressImageUpload(imageItem.path);
                        String newPathHead = imageItem.path;
                        updateMineMessage(newPathHead);
                    }
                }
            }
        }
    
    
    二、多张图片上传,选择后可删除,这里以最多九张图片为例。步骤与选择一张图片时基本一致,图片选择器稍微不同。

    1、布局中图片用RecyclerView

    <android.support.v7.widget.RecyclerView
                android:padding="5dp"
                android:id="@+id/recyclerView"
                android:layout_marginTop="12dp"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:choiceMode="singleChoice"
                android:divider="@null"
                android:fadingEdge="none"
                android:listSelector="@android:color/transparent"
                android:scrollbarStyle="outsideOverlay"
                app:layoutManager="android.support.v7.widget.GridLayoutManager"
                app:spanCount="4"
                tools:listitem="@layout/item_upload_image">
            </android.support.v7.widget.RecyclerView>
    

    2、初始化图片选择器。

    private void initImagePickerMulti() {
            ImagePicker imagePicker = ImagePicker.getInstance();
            imagePicker.setImageLoader(new GlideImageLoader());   //设置图片加载器
            imagePicker.setShowCamera(true);                      //显示拍照按钮
            imagePicker.setCrop(false);                            //允许裁剪(单选才有效)
            imagePicker.setSaveRectangle(true);                   //是否按矩形区域保存
            imagePicker.setSelectLimit(maxImgCount);              //选中数量限制
            imagePicker.setMultiMode(true);                      //多选
    //        imagePicker.setStyle(CropImageView.Style.RECTANGLE);  //裁剪框的形状
    //        imagePicker.setFocusWidth(800);                       //裁剪框的宽度。单位像素(圆形自动取宽高最小值)
    //        imagePicker.setFocusHeight(800);                      //裁剪框的高度。单位像素(圆形自动取宽高最小值)
    //        imagePicker.setOutPutX(1000);                         //保存文件的宽度。单位像素
    //        imagePicker.setOutPutY(1000);                         //保存文件的高度。单位像素
        }
    

    3、图片适配器。

    public class ImagePickerAdapter extends RecyclerView.Adapter<ImagePickerAdapter.SelectedPicViewHolder> {
        private int maxImgCount;
        private Context mContext;
        private List<ImageItem> mData;
        private LayoutInflater mInflater;
        private OnRecyclerViewItemClickListener listener;
        private boolean isAdded;   //是否额外添加了最后一个图片
        private OnItemRemoveClick onItemRemoveClick;
    
        public boolean isAdded() {
            return isAdded;
        }
    
        public void setAdded(boolean added) {
            isAdded = added;
        }
    
        public void setOnItemRemoveClick(OnItemRemoveClick onItemRemoveClick) {
            this.onItemRemoveClick = onItemRemoveClick;
        }
    
        public interface OnRecyclerViewItemClickListener {
            void onItemClick(View view, int position);
        }
    
        public void setOnItemClickListener(OnRecyclerViewItemClickListener listener) {
            this.listener = listener;
        }
    
        public void setImages(List<ImageItem> data) {
            mData = new ArrayList<>(data);
            if (getItemCount() < maxImgCount) {
                mData.add(new ImageItem());
                isAdded = true;
            } else {
                isAdded = false;
            }
            notifyDataSetChanged();
        }
        public void addImg() {
            if (getItemCount() < maxImgCount) {
                mData.add(new ImageItem());
                isAdded = true;
            } else {
                isAdded = false;
            }
        }
    
        public List<ImageItem> getImages() {
            //由于图片未选满时,最后一张显示添加图片,因此这个方法返回真正的已选图片
            if (isAdded) return new ArrayList<>(mData.subList(0, mData.size() - 1));
            else return mData;
        }
    
        public ImagePickerAdapter(Context mContext, List<ImageItem> data, int maxImgCount) {
            this.mContext = mContext;
            this.maxImgCount = maxImgCount;
            this.mInflater = LayoutInflater.from(mContext);
            setImages(data);
        }
    
        @Override
        public SelectedPicViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new SelectedPicViewHolder(mInflater.inflate(R.layout.item_upload_image, parent, false));
        }
    
        @Override
        public void onBindViewHolder(SelectedPicViewHolder holder, int position) {
            holder.bind(position);
        }
    
        @Override
        public int getItemCount() {
            return mData.size();
        }
    
        public class SelectedPicViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    
            private RelativeLayout cancelImg;
            private int clickPosition;
            private ImageView iv_img;
    
            public SelectedPicViewHolder(View itemView) {
                super(itemView);
                iv_img = (ImageView) itemView.findViewById(R.id.iv_img);
                cancelImg = ((RelativeLayout) itemView.findViewById(R.id.item_upload_image_cancelImg));
            }
    
            public void bind(final int position) {
                //设置条目的点击事件
                itemView.setOnClickListener(this);
                //根据条目位置设置图片
                ImageItem item = mData.get(position);
                if (isAdded && position == getItemCount() - 1) {
                    iv_img.setScaleType(ImageView.ScaleType.FIT_XY);
                    cancelImg.setVisibility(View.INVISIBLE);
                    iv_img.setImageResource(R.mipmap.img_add);
                    clickPosition = UploadMoreImagesActivity.IMAGE_ITEM_ADD;
                } else {
                    iv_img.setScaleType(ImageView.ScaleType.CENTER_CROP);
                    cancelImg.setVisibility(View.VISIBLE);
                    ImagePicker.getInstance().getImageLoader().displayImage((Activity) mContext, item.path, iv_img, 0, 0);
                    clickPosition = position;
                }
                cancelImg.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        removeItem(position);
                        onItemRemoveClick.onItemRemoveClick();
                    }
                });
            }
    
            @Override
            public void onClick(View v) {
                if (listener != null) listener.onItemClick(v, clickPosition);
            }
        }
    
        /**
         * 删除某条item
         * @param position
         */
        public void removeItem(int position){
            mData.remove(position);
    //        notifyItemRemoved(position);
        }
    
        public interface OnItemRemoveClick {
            public void onItemRemoveClick();
        }
    
    }
    

    4、适配器中选择图片的点击事件。adapter.setOnItemClickListener(this);

    @Override
        public void onItemClick(View view, int position) {
            switch (position){
                case IMAGE_ITEM_ADD:
                    //先请求权限,再进行操作
                    AndPermission.with(this)
                            .requestCode(300)
                            .permission(
                                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                    Manifest.permission.READ_EXTERNAL_STORAGE)
                            .callback(this)
                            .start();
    
                    break;
                default:
                    //打开预览
                    Intent intentPreview = new Intent(this, ImagePreviewDelActivity.class);
                    intentPreview.putExtra(ImagePicker.EXTRA_IMAGE_ITEMS, (ArrayList<ImageItem>) adapter.getImages());
                    intentPreview.putExtra(ImagePicker.EXTRA_SELECTED_IMAGE_POSITION, position);
                    intentPreview.putExtra(ImagePicker.EXTRA_FROM_ITEMS,true);
                    startActivityForResult(intentPreview, REQUEST_CODE_PREVIEW);
                    break;
            }
        }
    

    5、适配器中图片删除。

    adapter.setOnItemRemoveClick(new ImagePickerAdapter.OnItemRemoveClick() {
                @Override
                public void onItemRemoveClick() {
                    adapter.setImages(adapter.getImages());
                    adapter.notifyDataSetChanged();
                    selImageList.clear();
                    selImageList.addAll(adapter.getImages());
                }
            });
    

    6、发布时需要将图片上传至服务器,这里以 严振杰的NoHttp为例。(没有实际测试)

     /**
         * 上传图片到服务器
         */
        private void upLoadImages() {
            StringRequest request = new StringRequest("rul", RequestMethod.POST);
            request.addHeader("", "");
            request.add("content",contentEt.getText().toString());
            for (int i = 0; i < selImageList.size(); i++) {
                ImageItem imageItem = selImageList.get(i);
                String newPath = imageItem.path;
                File oldFile = new File(newPath);
                File newFile = CompressHelper.getDefault(getApplicationContext()).compressToFile(oldFile);
                request.add("imgs"+(i+1),newFile);
            }
            requestData(request, new SimpleResponseListener<String>() {
                @Override
                public void onStart(int what) {
                    super.onStart(what);
                }
    
                @Override
                public void onSucceed(int what, Response<String> response) {
                    super.onSucceed(what, response);
                    //上传成功
                }
            });
        }
    

    下载Demo查看效果【各位小可爱们如果觉得效果需要,可以小小的赞赏一下~~么么哒】

    uploadimgsdemo.png

    相关文章

      网友评论

          本文标题:Android调用系统相机、本地相册上传图片(头像上传(裁剪)、

          本文链接:https://www.haomeiwen.com/subject/emflgxtx.html