Android仿微信添加照片并且随意限制照片数量并显示缩略图界面

前段时间做项目时产品加入一个新功能,拍照并显示缩略图,之前我们公司的都是只显示拍了几张照片 然后点击之后跳到另外一个界面显示这几张照片,自我感觉这种方式很是不方便,就趁次机会做了一个实用并且通用的拍照显示工具,先看效果

这是拍照过程中,如果没有达到设定的拍照数量那么拍照按钮就显示着还可以继续拍

当拍照数量达到设定的数量后最后的拍照按钮隐藏,我在这里设置的9张照片,你用的时候可以随意设置

一、实现这个功能主要在于适配器怎么写,其实逻辑也比较简单,我们定一个数字作为照片数量的限制,然后在适配器getCount()方法中用这个值和现有照片数量做对比然后返回相应的数量即可,写的demo,所以主界面很简单 就一个GridView,其实现在可以用recycleview代替现有的Listview和GridView,比如前几天我就遇到一个这个问题,产品原型画出来了,效果图还没出来,数据也没有,但我们不能等他们要先用假数据做界面,其中一个界面是这样的,就是一个列表,每个item是一张图对应一句话,原型是一行一个,我就想着先用listview把效果实现了,等设计和数据来了稍作修改即可,可不曾想设计图出来后傻了,设计觉得每行显示一列不好看,设计成了每行两列,这就意味着我要重新换控件,如果以后界面再改又要换,所以直接用了recycleview,这样以后管他横排竖排横滑竖滑只需对recycleview进行设置即可,话说回来,我们这里还暂用GridView,因为我不想再换了,想换可以自行修改

二、主界面就是拍照然后刷新适配器这些操作,我们直接看adapter

item布局要注意一下,因为要包含图片和拍照按钮

代码如下:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@drawable/selector_presse"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/iconImageView"
        android:layout_width="match_parent"
        android:layout_height="130dp"
        android:background="@null"
        android:scaleType="fitXY"
        android:src="@drawable/defelt_icon" />

    <FrameLayout
        android:id="@+id/framelayout_add_pic"
        android:layout_width="match_parent"
        android:layout_height="130dp"
        android:background="@color/gray_bg_color" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="130dp"
            android:gravity="center"
            android:orientation="vertical" >

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="+"
                android:textColor="@color/gray_text_color"
                android:textSize="40dp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="添加图片"
                android:textColor="@color/gray_text_color" />
        </LinearLayout>
    </FrameLayout>

</LinearLayout>

由于拍照按钮用照片的话在不同手机上显示效果不同,有可能会变形,所以用了布局的方式,图片加文字,这样看着就会很自然,再看适配器主要是getcount()方法

 

 

@Override
	public int getCount() {
		int size = 1;
		if (mPictures.size() >= mNums) {
			// 限制拍照数量mNums张
			size = mPictures.size();
		} else {
			size += mPictures.size();
		}
		return size;
	}

这里面的mNums是传进来的 用于限定拍照数量,拍照按钮显示与否是要靠返回的size控制,这里至少要返回1,因为一开始要显示拍照按钮,如果没有达到设定数量,那么每次返回的数量要+1,给拍照按钮留下位置,如果达到数量那么就直接返回照片数量,不需多返回一个位置,至于显示照片还是添加照片按钮要在下面的getView()种控制。构造如下:其中CreateBmpFactory是拍照的一个工具类,稍后我会上传完整demo

public PhotoAdapter(List<String> mPictures, int mNums, CreateBmpFactory mCreateBmpFactory, Context mContext) {
		super();
		this.mPictures = mPictures;
		this.mCreateBmpFactory = mCreateBmpFactory;
		this.mContext = mContext;
		this.mNums = mNums;
	}

然后另一关键处是getView()方法里要靠position和照片集合的size对比,因为position是从0开始,而size是从1开始,所以正常情况下position总是比size小,所以当position==mPictures.size()的时候说明此时getCount()多返回了一个位置,此时就是拍照数量没达到设定值需要显示拍照按钮(这个地方有点绕),来看getView()方法:

@Override
	public View getView(final int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = LayoutInflater.from(mContext).inflate(R.layout.layout_picture, parent, false);
			holder.iv_icon = (ImageView) convertView.findViewById(R.id.iconImageView);
			holder.framelayout_add_pic = (FrameLayout) convertView.findViewById(R.id.framelayout_add_pic);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}

		if (position == mPictures.size()) {
			holder.iv_icon.setVisibility(View.GONE);
			holder.framelayout_add_pic.setVisibility(View.VISIBLE);
		} else {
			holder.iv_icon.setVisibility(View.VISIBLE);
			holder.framelayout_add_pic.setVisibility(View.GONE);
			holder.iv_icon.setTag(mPictures.get(position).toString());
			new GetBitmapTask().execute(holder.iv_icon);
		}
		convertView.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				if (position == mPictures.size()) {

					AlertDialog.Builder builder = new AlertDialog.Builder(mContext );
					builder.setTitle("请选择操作");
					final String[] menu = { "拍照", "从图库中选择" };
					builder.setItems(menu, new DialogInterface.OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							switch (which) {
							case 0:
								mCreateBmpFactory.OpenCamera();
								break;

							case 1:
								mCreateBmpFactory.OpenGallery();
								break;
							}
						}
					});
					builder.show();
				} else {

					AlertDialog.Builder builder = new Builder(mContext).setTitle("查看大图");
					View view = LayoutInflater.from(mContext).inflate(R.layout.layout_img_dialog, null);
					ImageView bigPhoto = ((ImageView) view.findViewById(R.id.bigPic));
					bigPhoto.setImageBitmap(BitmapFactory.decodeFile(mPictures.get(position).toString()));
					builder.setView(view).setPositiveButton("删除", new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							// 删除图片
							mPictures.remove(position);
							notifyDataSetChanged();
						}
					}).setNegativeButton("返回", null).create().show();
				}
			}
		});

		return convertView;
	}

主要判断在于这:

 

 

if (position == mPictures.size()) {
			holder.iv_icon.setVisibility(View.GONE);
			holder.framelayout_add_pic.setVisibility(View.VISIBLE);
		} else {
			holder.iv_icon.setVisibility(View.VISIBLE);
			holder.framelayout_add_pic.setVisibility(View.GONE);
			holder.iv_icon.setTag(mPictures.get(position).toString());
			new GetBitmapTask().execute(holder.iv_icon);
		}

当然那个弹框看大图的只是实现以下点击事件,这里你可以进行你自己的其他操作。由于显示的是图片所以会有一个问题就是图片过大时候会比较卡,比如你项目里用的时候肯定是要保存图片然后进行回显的,这时候直接主线程里加载就会很卡,所以显示照片的操作可以放在线程里面做,上面的new GetBitmapTask().execute(holder.iv_icon)就是用来异步加载的,具体实现如下:

class GetBitmapTask extends AsyncTask<ImageView, Void, ImageView> {
		Bitmap bitmap = null;
		ImageView view = null;

		@Override
		protected ImageView doInBackground(ImageView... params) {
			// TODO Auto-generated method stub
			view = params[0];
			String path = view.getTag().toString();
			bitmap = BitmapHelp.getSmallBitmap(path);
			return view;
		}

		@Override
		protected void onPostExecute(ImageView v) {
			// TODO Auto-generated method stub
			v.setImageBitmap(bitmap);
			super.onPostExecute(v);
		}
	}

传入控件,把照片的路径以Tag的方式设置给控件即可。至此功能完美实现。

需要demo的小伙伴可以加qq群自行下载(TakePhotoAdapter.zip):579699145
 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值