热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

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

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

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

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

3.从相册中选择图片

 3.1 获取手机中的所有图片

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

 3.3 自定义ViewPager浏览图片

.

.

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

一、首先看一下界面:

是一个 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


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

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

//从图库选择的图片model
public class ImageItem extends File implements Serializable {
	@Id
	public String imageId; //图片id
	public 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 block
				e.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中
         * 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 ids = new ArrayList();
//            for (int i=0;i

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



    
        

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

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

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

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

// 初始化,给一些对象赋值
	private void init() {
		helper = AlbumHelper.getHelper();
		helper.init(getApplicationContext());
		
		cOntentList= helper.getImagesBucketList(false);
		dataList = new ArrayList();
		for(int i = 0; i


gridImageAdapter
				.setOnItemClickListener(new AlbumGridViewAdapter.OnItemClickListener() {

					@Override
					public 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

下面贴两张截图吧:

技术分享技术分享技术分享技术分享技术分享






版权声明:本文为博主原创文章,未经博主允许不得转载。

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


推荐阅读
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • 在project.properties添加#Projecttarget.targetandroid-19android.library.reference.1..Sliding ... [详细]
author-avatar
埃菲尔的天空有什么
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有