安卓选择图片上传功能【支持多选拍照预览等】

在网上找了很多第三方的相册拍照框架,都不尽人意,最后终于找到了一个比较好的框架,并且集成到了自己的demo中,花了两天的时间吧感觉挺值的。老规矩不说废话,直接上代码。

感谢某开源库的作者:Alum

以及本文的案例地址:Demo_ChooseImg

思路


目录


先看目录,我尽可能的在自己力所能及的范围内,用最简单的方式和代码来实现。这里最重要的玩意儿是那个适配器。最下面的那个popupwindow是个自己写的控件,如果有兴趣我回头再把这个玩意儿放出来。

先看看功能吧:


功能


简单来说就是点击加号可以新增或拍照,拍照后可直接返回到主页面直接更新图片。可以控制选择的图片数量,主题,以及预览等等。

先看布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <GridView
        android:id="@+id/gvImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:horizontalSpacing="5dp"
        android:numColumns="3"
        android:verticalSpacing="5dp" />

</LinearLayout>

主页只有一个GridView+适配器
然后看一下每一个item的布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <!--显示图片-->
    <RelativeLayout
        android:id="@+id/rlItemShow"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="?android:attr/selectableItemBackground"
        android:visibility="gone">

        <com.facebook.drawee.view.SimpleDraweeView
            android:id="@+id/sdvItemShowImg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            fresco:actualImageScaleType="fitXY"
            fresco:placeholderImage="@color/blue1"
            fresco:placeholderImageScaleType="fitXY" />

        <!--删除图片-->
        <ImageView
            android:id="@+id/ivDeleteImg"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentRight="true"
            android:layout_margin="5dp"
            android:scaleType="fitXY"
            android:src="@mipmap/ic_delete_img" />

    </RelativeLayout>

    <!--添加图片-->
    <ImageView
        android:id="@+id/ivItemAdd"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:background="@drawable/shape_iv_add_img"
        android:padding="20dp"
        android:scaleType="centerInside"
        android:src="@mipmap/ic_plus_img"
        android:visibility="gone" />

</LinearLayout>

手动控制一下宽高,这里对于每一个item来说,可以坐三件事情,显示图片,删除图片,新增图片。其中,点击显示的图片可以跳转到预览界面,点击删除图片可以删除被点的这张,点击新增图片跳转到相册。这个逻辑应该是简单而又清晰的。

那么我们主要来看一下适配器

public class ImgGridAdapter extends BaseAdapter {

    private Context context;
    private ArrayList<String> imgList;
    private int maxImgCount;
    private FreshImgCallBack freshImgCallBack;//针对三种操作逻辑所自定义的回调

    public ImgGridAdapter(Context context, ArrayList<String> imgList, int maxImgCount) {
        this.context = context;
        this.imgList = imgList;
        this.maxImgCount = maxImgCount;
    }

    /**
     * 设置回调
     *
     * @param callBack freshImgCallBack
     */
    public void setImgShowFresh(FreshImgCallBack callBack) {
        freshImgCallBack = callBack;
    }

    @Override
    public int getCount() {
        if (imgList.size() < maxImgCount) {
            return imgList.size() + 1;
        } else {
            return maxImgCount;
        }
    }

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

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

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (holder != null) {
            holder = (ViewHolder) convertView.getTag();
        } else {
            holder = new ViewHolder();
            convertView = LayoutInflater.from(context).inflate(R.layout.itme_gridview, null);
            holder.sdvItemShowImg = (SimpleDraweeView) convertView.findViewById(R.id.sdvItemShowImg);
            holder.ivDeleteImg = (ImageView) convertView.findViewById(R.id.ivDeleteImg);
            holder.ivItemAdd = (ImageView) convertView.findViewById(R.id.ivItemAdd);
            holder.ivItemAdd.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    freshImgCallBack.openGallery();//打开相册放在里面即可
                }
            });
            holder.rlItemShow = (RelativeLayout) convertView.findViewById(R.id.rlItemShow);
        }
        //——————————————————————————————设置图片逻辑——————————————————————————————
        holder.ivItemAdd.setVisibility(View.GONE);
        holder.rlItemShow.setVisibility(View.GONE);
        if (imgList.size() < 5) {
            if (position == getCount() - 1) {
                holder.ivItemAdd.setVisibility(View.VISIBLE);
            } else {
                if (getCount() > 1) {
                    showImg(position, holder);
                }
            }
        } else {
            showImg(position, holder);
        }

        //放在外面用于更新position
        holder.sdvItemShowImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                freshImgCallBack.previewImg(position);//预览图片
            }
        });
        holder.ivDeleteImg.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                freshImgCallBack.updateGvImgShow(position);//更新数据
            }
        });
        return convertView;
    }

    //显示图片
    private void showImg(int position, ViewHolder holder) {
        holder.ivItemAdd.setVisibility(View.GONE);
        holder.rlItemShow.setVisibility(View.VISIBLE);
        //设置图片
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse("file://" + imgList.get(position)))
                .setProgressiveRenderingEnabled(true)
                .setResizeOptions(new ResizeOptions(100, 100))
                .build();
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setImageRequest(request)
                .setAutoPlayAnimations(true)
                .setTapToRetryEnabled(true)
                .setOldController(holder.sdvItemShowImg.getController())
                .build();
        holder.sdvItemShowImg.setController(controller);
    }

    class ViewHolder {
        SimpleDraweeView sdvItemShowImg;
        ImageView ivDeleteImg;
        ImageView ivItemAdd;
        RelativeLayout rlItemShow;
    }

}

粗略看了一下一百多行,应该不算多吧- -!这里使用了Fresco是因为自己的项目里面用了这个框架,并且这里针对缩略图做了压缩处理。

针对如何显示新增图片,这里把逻辑理了一下:如果图片数量小于最大数量,那么就让gridview多显示一个,并且最后一个item只显示新增,否则就显示所有的图片。控制可见不可见对于内存资源的消耗相对较少。

适配器就是原生的适配器,我在里面写了一个接口的实现,用于在外部暴露一个入口来刷新图片。这里主要使用了观察者模式,不懂的同学自行学习接口回调。这里不再赘述。

看一下我定义的接口:

public interface FreshImgCallBack {

    void previewImg(int position);//用于预览图片

    void updateGvImgShow(int position);//用于刷新GridView

    void openGallery();//用于打开相册

}

然后我们在Activity里面去实现它

public class MainActivity extends AppCompatActivity implements FreshImgCallBack {

    private static final int REQUEST_CODE_GALLERY = 100;//打开相册
    private static final int REQUEST_CODE_PREVIEW = 101;//预览图片

    private GridView gvImage;
    private ImgGridAdapter adapter;
    private ArrayList<String> imgList = new ArrayList<>();
    private final static int maxImgSize = 5;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        gvImage = (GridView) findViewById(R.id.gvImage);
        adapter = new ImgGridAdapter(this, imgList, maxImgSize);
        adapter.setImgShowFresh(this);//实现刷新接口
        gvImage.setAdapter(adapter);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case REQUEST_CODE_GALLERY:
                if (resultCode == RESULT_OK) {
                    imgList.clear();//不可直接指向
                    for (int i = Album.parseResult(data).size() - 1; i < 0; i++) {
                        imgList.add(Album.parseResult(data).get(i));//控制图片顺序
                    }
                    adapter.notifyDataSetChanged();
                }
                break;
        }
    }

    //更新图片:当前用于删除
    @Override
    public void updateGvImgShow(int position) {
        imgList.remove(position);
        adapter.notifyDataSetChanged();
    }

    @Override
    public void openGallery() {
        Album.album(this)//打开相册
                .requestCode(REQUEST_CODE_GALLERY)
                .toolBarColor(ContextCompat.getColor(this, R.color.colorPrimary))
                .statusBarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark))
                .selectCount(maxImgSize)
                .columnCount(3)
                .camera(true)
                .checkedList(imgList)
                .start();
    }

    @Override
    public void previewImg(int position) {
        Album.gallery(this)//预览图片
                .requestCode(REQUEST_CODE_PREVIEW)
                .toolBarColor(ContextCompat.getColor(this, R.color.colorPrimary))
                .statusBarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark))
                .checkedList(imgList)
                .currentPosition(position)
                .checkFunction(false)
                .start();
    }

}

然后大功告成,这个逻辑应该是很简单的吧,实现方式应该也很简单。然后对于相册的功能,我引入的框架地址在文章头部已经标出来了。使用方法在github上面都写的很清楚。如果需要的话我后期会在本文下面列出使用教程。

GitHub DEMO 地址

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值