【Android源码解析】选择多张图片上传多图预览

来源:互联网 发布:陈丹丹淘宝店叫什么 编辑:程序博客网 时间:2024/06/05 00:12

   最近做了选择多图并且上传服务器,在网上找了一些demo,适当的做了一下调整,用过了不能忘记,记下来以后还能多看看,本人觉得自己的博客有些渣渣,还希望大家不要介意啊,哪里有错误希望大家及时指正。

  好了下面具体的分析一下:(想要做出功能,需求分析是必不可少的,需求、逻辑弄懂了再上手写代码,思路会很清晰的)

1.多图上传首先得选择图片(这里项目需求是既可以拍照上传也可以从相册中选择)

2.拍照上传很简单了网上也有很多例子,调用照相机,返回uri,获取图片

3.从相册中选择图片

 3.1 获取手机中的所有图片

 3.2 将图片存到自定义图片数组中显示

 3.3 自定义ViewPager浏览图片

.

.

主要的逻辑大体是这样,下面具体看一下实现:

一、首先看一下界面:

<com.view.NoScrollGridView                    android:id="@+id/noScrollgridview"                    android:layout_marginLeft="@dimen/smaller_space"                    android:layout_marginRight="@dimen/smaller_space"                    android:layout_width="match_parent"                    android:layout_height="wrap_content"                    android:horizontalSpacing="3dp"                    android:listSelector="@color/transparent"                    android:numColumns="3"                    android:scrollbars="none"                    android:layout_gravity="center"                    android:layout_marginTop="@dimen/smaller_space"                    android:verticalSpacing="5dp" />

是一个 NoScrollGridView,项目需要,所以用了不滚动的GridView,大家用GridView也是一样的。

noScrollgridview = (GridView) findViewById(R.id.noScrollgridview);        noScrollgridview.setSelector(new ColorDrawable(Color.TRANSPARENT));        /*新建传值给adapter*/        if (file == null) {            picAdapter = new PictureAdapter(this, 0, null);        } else {            //添加失败的图片到数组中            for (int i=0;i<file.getMulFailFilePaths().length;i++){                ImageItem imageItem = new ImageItem();                imageItem.setImagePath(file.getMulFailFilePaths()[i].trim());                Bimp.tempSelectBitmap.add(imageItem);            }            /*上传失败传值给adapter*/            picAdapter = new PictureAdapter(this, 2, file);        }


这个是初始化图片数组,适配器(新建、上传失败、上传成功的图片我用的都是一个adapter)

ImageItem是图片的模型,下面有它的属性

//从图库选择的图片modelpublic class ImageItem extends File implements Serializable {@Idpublic String imageId; //图片idpublic String thumbnailPath; public String imagePath; //图片路径private Bitmap bitmap; public boolean isSelected = false;public String getImageId() {return imageId;}public void setImageId(String imageId) {this.imageId = imageId;}public String getThumbnailPath() {return thumbnailPath;}public void setThumbnailPath(String thumbnailPath) {this.thumbnailPath = thumbnailPath;}public String getImagePath() {return imagePath;}public void setImagePath(String imagePath) {this.imagePath = imagePath;}public boolean isSelected() {return isSelected;}public void setSelected(boolean isSelected) {this.isSelected = isSelected;}
/*根据图片路径获取图片的bitmap*/public Bitmap getBitmap() {if(bitmap == null){try {bitmap = Bimp.revitionImageSize(imagePath);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return bitmap;}public void setBitmap(Bitmap bitmap) {this.bitmap = bitmap;}}

接下来是适配器:

由于涉及到添加图片,adapter中添加一个flag用来显示新建的图片,将选择的图片添加到公有的图片数组中,初始化的时候加载图片数组显示。(大家在看的时候可以忽略掉我的flag)

@SuppressLint("HandlerLeak")public class PictureAdapter extends BaseAdapter {    private LayoutInflater inflater;    private int selectedPosition = -1;    private boolean shape;    private int flag = 0;//0 默认新建 1上传成功 2上传失败    private AppItem_file file;    public boolean isShape() {        return shape;    }    private Activity context;    public void setShape(boolean shape) {        this.shape = shape;    }    public PictureAdapter(Activity context,int flag,AppItem_file file) {        this.context = context;        inflater = LayoutInflater.from(context);        this.flag = flag;        this.file = file;    }//    public void update() {//        loading();//    }    public int getCount() {        if (flag==0){   //新建图片            if (Bimp.tempSelectBitmap.size() == 6) {                return 6;            }            return (Bimp.tempSelectBitmap.size() + 1);        }        else if (flag==1){  //上传成功            return file.getFileList().size();        }        else {  //上传失败            return file.getMulFailFilePaths().length;        }    }    public Object getItem(int arg0) {        if (flag==1){            return file.getFileList().get(arg0);        }else {            return file.getMulFailFilePaths()[arg0];        }    }    public long getItemId(int arg0) {        return arg0;    }    public void setSelectedPosition(int position) {        selectedPosition = position;    }    public int getSelectedPosition() {        return selectedPosition;    }    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;        if (convertView == null) {            //根据图片的数量加载不同布局            if (getCount()==1&&flag!=0){                convertView = inflater.inflate(R.layout.item_published_singal_item,                        parent, false);            }            else {                convertView = inflater.inflate(R.layout.item_published_grida,                        parent, false);            }            holder = new ViewHolder();            holder.image = (ImageView) convertView                    .findViewById(R.id.item_grida_image);            convertView.setTag(holder);        } else {            holder = (ViewHolder) convertView.getTag();        }        /**         * 根据初始化adapter传过来的flag值,去不同的地方找图片         * flag=0,去Bimp的图片数组中找         * flag=1,证明上传成功的,去下载好的getFileList中找         * flag=2,为上传失败的,图片保存在FailFile中的List<ImageItem>中         * by黄海杰 at:2015年7月16日 09:51:25         * 优化图片显示         * by黄海杰 at:2015年8月3日 17:09:01         */        if (flag==0){   //新建图片            if (position == Bimp.tempSelectBitmap.size()) {                holder.image.setImageBitmap(BitmapFactory.decodeResource(                        convertView.getResources(), R.drawable.icon_add_pic_unfocused));                if (position == 6) {                    if (flag==0){                        holder.image.setVisibility(View.GONE);                    }                }            } else {                holder.image.setImageBitmap(Bimp.tempSelectBitmap.get(position).getBitmap());            }        }        else if (flag==1){  //上传成功//            List<Integer> ids = new ArrayList<Integer>();//            for (int i=0;i<file.getFileList().size();i++){//                ids.add(file.getFileList().get(i).getS_id());//            }            int id=file.getFileList().get(position).getS_id();            try {//                File file= NeedApplication.db.findById(File.class,id);                String fileBigImgUri =NeedApplication.db.findById(File.class,id).getFileUriBig();                if (fileBigImgUri!=null&&!"null".equals(fileBigImgUri))                ImageLoader.getInstance().displayImage((fileBigImgUri).trim(),holder.image);            } catch (DbException e) {                e.printStackTrace();            }        }        else {  //上传失败                String url = "file://"+file.getMulFailFilePaths()[position].trim();                ImageLoader.getInstance().displayImage(url, holder.image);        }        return convertView;    }    public class ViewHolder {        public ImageView image;    }}

下面是自定义相册界面,用来选择图片的

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"     android:background="#E1E0DE"    >    <RelativeLayout        android:id="@+id/headview"        android:layout_width="fill_parent"        android:layout_height="45dp"        android:background="@drawable/plugin_camera_title_bar"        android:gravity="center_vertical"        android:layout_marginBottom="3dp"        >        <Button            android:layout_width="60dp"            android:layout_height="wrap_content"            android:textSize="14sp"            android:textColor="#fff"            android:id="@+id/back"            android:text="相册"            android:background="@drawable/plugin_camera_title_btn_back"            android:layout_marginTop="5dp"            android:layout_marginBottom="5dp"            android:layout_centerVertical="true"            />        <Button            android:layout_width="67dp"           android:layout_height="wrap_content"        android:textSize="14sp"        android:textColor="#fff"        android:id="@+id/cancel"        android:text="取消"        android:background="@drawable/plugin_camera_title_btn_cancel"          android:layout_centerVertical="true"          android:layout_marginRight="5dp"            android:layout_alignParentRight="true"             />    </RelativeLayout>    <RelativeLayout        android:id="@+id/bottom_layout"        android:layout_width="match_parent"        android:layout_height="50dp"        android:layout_alignParentBottom="true"        android:background="@drawable/plugin_camera_bottom_bar"        android:layout_marginTop="3dp"        > <Button            android:id="@+id/preview"            android:layout_width="90dp"            android:layout_height="wrap_content"            android:layout_alignParentLeft="true"            android:layout_centerVertical="true"            android:layout_marginLeft="10dp"            android:text="预览"            android:background="@drawable/plugin_camera_title_btn_preview"            />        <Button            android:id="@+id/ok_button"            android:layout_width="90dp"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:layout_centerVertical="true"            android:layout_marginRight="10dp"            android:background="@drawable/plugin_camera_ok_btn_state"            />    </RelativeLayout>    <GridView        android:id="@+id/myGrid"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_above="@id/bottom_layout"        android:layout_below="@id/headview"        android:layout_centerInParent="true"        android:layout_marginTop="2dp"        android:horizontalSpacing="10dp"        android:numColumns="4"        android:verticalSpacing="10dp"        android:background="#E1E0DE" />    <TextView        android:id="@+id/myText"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:gravity="center"        android:text="相册没有图片"        android:textColor="@color/black"        /></RelativeLayout>

同样也是用了GridView,获取手机中的图片,添加到数组中,显示

这里用到了一个AlbumHelper(相册帮助类),网上找的代码,感觉挺好的

public List<ImageBucket> getImagesBucketList(boolean refresh) {if (refresh || (!refresh && !hasBuildImagesBucketList)) {buildImagesBucketList();}List<ImageBucket> tmpList = new ArrayList<ImageBucket>();Iterator<Entry<String, ImageBucket>> itr = bucketList.entrySet().iterator();while (itr.hasNext()) {Entry<String, ImageBucket> entry = (Entry<String, ImageBucket>) itr.next();tmpList.add(entry.getValue());}return tmpList;}

获取到数据源之后,该显示了,也就是利用的获取图片帮助类里面的方法

// 初始化,给一些对象赋值private void init() {helper = AlbumHelper.getHelper();helper.init(getApplicationContext());contentList = helper.getImagesBucketList(false);dataList = new ArrayList<ImageItem>();for(int i = 0; i<contentList.size(); i++){dataList.addAll( contentList.get(i).imageList );}back = (Button) findViewById(R.id.back);cancel = (Button) findViewById(R.id.cancel);cancel.setOnClickListener(new CancelListener());back.setOnClickListener(new BackListener());preview = (Button) findViewById(R.id.preview);preview.setOnClickListener(new PreviewListener());intent = getIntent();Bundle bundle = intent.getExtras();gridView = (GridView) findViewById(R.id.myGrid);gridImageAdapter = new AlbumGridViewAdapter(mContext,dataList,Bimp.tempSelectBitmap);gridView.setAdapter(gridImageAdapter);tv = (TextView) findViewById(R.id.myText);gridView.setEmptyView(tv);okButton = (Button) findViewById(R.id.ok_button);okButton.setText("完成"+"(" + Bimp.tempSelectBitmap.size()+ "/"+ NeedApplication.picNums+")");}


gridImageAdapter.setOnItemClickListener(new AlbumGridViewAdapter.OnItemClickListener() {@Overridepublic void onItemClick(final ToggleButton toggleButton,int position, boolean isChecked,Button chooseBt) {if (Bimp.tempSelectBitmap.size() >= NeedApplication.picNums) {toggleButton.setChecked(false);chooseBt.setVisibility(View.GONE);if (!removeOneData(dataList.get(position))) {Toast.makeText(AlbumActivity.this, "超出可选图片张数", Toast.LENGTH_SHORT).show();}return;}if (isChecked) {chooseBt.setVisibility(View.VISIBLE);Bimp.tempSelectBitmap.add(dataList.get(position));okButton.setText("完成"+"(" + Bimp.tempSelectBitmap.size()+ "/"+ NeedApplication.picNums+")");} else {Bimp.tempSelectBitmap.remove(dataList.get(position));chooseBt.setVisibility(View.GONE);okButton.setText("完成"+"(" + Bimp.tempSelectBitmap.size() + "/"+ NeedApplication.picNums+")");}isShowOkBt();}});

点击图片选择加到公有图片数组中显示已选择

最后是预览图片,利用自定义viewpager,实现图片滑动.....代码就不占了,好多demo

下面贴两张截图吧:








1 0