神刀安全网

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


前言

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

感谢某开源库的作者:
https://github.com/yanzhenjie/Album

思路

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

目录

先看目录,我尽可能的在自己力所能及的范围内,用最简单的方式和代码来实现。这里最重要的玩意儿是那个适配器。最下面的那个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上面都写的很清楚。如果需要的话我后期会在本文下面列出使用教程。

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 安卓选择图片上传功能【支持多选拍照预览等】

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址