IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> android中的图片选择器,实现微信发布朋友圈多图选择上传功能 -> 正文阅读

[移动开发]android中的图片选择器,实现微信发布朋友圈多图选择上传功能

本片文章是根据项目要求的思路去学习其他的博主改良的思路,思路会有雷同,但是该文确实属于本人原文创作,参考链接会在文章最后展示(啊啊啊啊啊,好官方。。。。)

先说一下项目的功能要求,类似于QQ和微信在举报\投诉用户时的界面,需要要求用户上传相关违规的聊天截图,当然在实现这个功能之前用户是已经将截图保存到手机相册里的,所以这个多图上传的功能就比较简单了,当时在做这个功能的时候本人也是从网上查找了很多资料,我一开始的思路是用代码去调系统相册,然后从系统相册去选择图片,但是运行之后发现图片只能选择一张,不能多张选择,这不符合开发逻辑(主要原因还是自己经验不足,竟然不知道还有图片选择器这个框架),发现图片选择器的相关的框架种类还是有多的的,有原生的也有大牛直接用代码手敲出来的,(但是本人更喜欢原生的,因为大牛的思路并不是人人都能理解的。。。。)所以我就不多说大牛的了,我来例举几个原生的,初级码农还是容易理解的哦,不说了,直接来给大家介绍一下吧!

布局代码:只展示显示图片的那部分代码哈

<androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">
           
            <GridView
                android:id="@+id/add_pic"
                android:layout_width="200dp"
                android:layout_height="fill_parent"
                android:layout_marginStart="30dp"
                android:background="@drawable/input_bg"
                android:minHeight="56dp"
                android:scrollbars="none"
                android:layout_margin="10dp"
                android:visibility="gone"
                android:gravity="fill_horizontal"
                android:stretchMode="columnWidth"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintRight_toLeftOf="@id/btn_add_pic"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
//点击该按钮跳转到系统图片选择器中
            <Button
                android:id="@+id/btn_add_pic"
                android:layout_width="56dp"
                android:layout_height="56dp"
                android:layout_margin="10dp"
                android:background="@drawable/add_picture_bg"
                android:foreground="@mipmap/add"
                android:foregroundGravity="center"
                app:backgroundTint="#EFEFEF"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toEndOf="@+id/add_pic"
                app:layout_constraintTop_toTopOf="parent" />
                
        </androidx.constraintlayout.widget.ConstraintLayout>

按照项目要求做出来的布局是这样式的:
在这里插入图片描述

接下来是java代码的功能实现:

public   class btnAddPicOnClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
       		 //开启多图选择器
            Intent intent=new Intent(MainActivity.this, ImagesSelectorActivity.class);
            //设置选择图片的最大数量
            intent.putExtra(SelectorSettings.SELECTOR_MAX_IMAGE_NUMBER,3);
            //设置显示的图像的最小尺寸;过滤微小的图像(主要是图标)
            intent.putExtra(SelectorSettings.SELECTOR_MIN_IMAGE_SIZE,100000);
            //是否显示相机
            intent.putExtra(SelectorSettings.SELECTOR_SHOW_CAMERA,false);
            //将当前选定的图像集合作为初始值
            intent.putStringArrayListExtra(SelectorSettings.SELECTOR_INITIAL_SELECTED_LIST,imagePaths);
            //跳转到多图选择器中
            startActivityForResult(intent,REQUEST_CODE);
        }
    }
//获取图片路径 响应startActivityForResult 并将图片显示到网格布局中去
    @SuppressLint("LongLogTag")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //requestCode:状态标识码
        if (requestCode==REQUEST_CODE){
        //resultCode:结果标识码
            if (resultCode==RESULT_OK){
            //从选择器中获取选择结果
               ArrayList<String> list=data.getStringArrayListExtra(SelectorSettings.SELECTOR_RESULTS);
               //显示选中的图片
               loadAdapter(list);
                Log.i("jjjj", "list: "+ list.toString());
                //网格布局一开始是隐藏的,主要是为了显示的布局好看,在选中了图片之后再给他显示出来
               gvPic.setVisibility(View.VISIBLE);
               //给网格布局设置最大列数
               gvPic.setNumColumns(list.size());
            }
        }
    }

当然网格布局用的就是自定义适配器BaseAdapter代码如下:

private void loadAdapter(ArrayList<String> paths){
	//首先清空图片路径的集合
        if (imagePaths!=null&& imagePaths.size()>0){
            imagePaths.clear();
        }
    //同样清出掉paths里的没用的数据
        if (paths.contains("000000")){
            paths.remove("000000");
        }
//        paths.add("000000");
        imagePaths.addAll(paths);
        adapter=new GridAdapter(imagePaths,MainActivity.this);
//        adapter.notifyDataSetChanged();
        gvPic.setAdapter(adapter);
    }

    private class GridAdapter extends BaseAdapter{
    //创建入口参数,数据列表,布局填充器,上下文内容
        private ArrayList<String> listUrls;
        private LayoutInflater inflater;
        private Context context;
        public GridAdapter(ArrayList<String> listUrls,Context context){
            this.listUrls=listUrls;
            this.context=context;
            inflater=LayoutInflater.from(MainActivity.this);
        }
     //获取列表数据有几条
        @Override
        public int getCount() {
            return listUrls.size();
        }
	//获取列表中的某一条数据
        @Override
        public Object getItem(int position) {
            return listUrls.get(position);
        }
	//获取列表中的某条数据的位置
        @Override
        public long getItemId(int position) {
            return position;
        }
	//绘制列表
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
        //实列化视图持有者类
            ViewHolder holder=null;
            //对内容视图判空
            if (convertView==null){
                holder=new ViewHolder();
                //填充内容视图(R.layout.add_pic_item为网格布局的子布局)
                convertView=inflater.inflate(R.layout.add_pic_item,parent,false);
                //将内容视图中的控件id赋值给视图持有者中控件
                holder.image=(ImageView) convertView.findViewById(R.id.img_pic);
                holder.image.setBackground(getResources().getDrawable(R.drawable.add_picture_bg));
                convertView.setTag(holder);
            }else {
                holder= (ViewHolder) convertView.getTag();
            }
//将图片布置到视图中去
            final String path=listUrls.get(position);
            if (path.equals("000000")){
//                    holder.image.setImageResource(R.mipmap.ic_launcher);
//                listUrls.clear();
                listUrls.remove("000000");
            }else{
            //通过Glide图片缓存机制框架加载图片
                Glide.with(MainActivity.this)
                        .load(path)
                        .placeholder(R.mipmap.ic_launcher_round)
                        .error(R.mipmap.ic_launcher_round)
                        .centerCrop()
                        .crossFade()
                        .into(holder.image);
                   //如果图片数量达到了3张就隐藏添加按钮来控制用户行为
                if(listUrls.size()==3){
//                Toast.makeText(context, "只能选择3张哦!", Toast.LENGTH_SHORT).show();
                    btnAddPic.setVisibility(View.GONE);
                }
            }
            return convertView;
        }
        //创建视图持有者类
        class ViewHolder{
            ImageView image;
        }
    }

在写java代码的时候需要注意的点:

1.写java代码时在项目中添加“multiple-images-selector”多图选择器的依赖:
2. 开启图片选择器的时候需要开启读取系统相册的权限以及网络访问权限。
3. 添加图片选择器图片。

//在build.gradle文件中添加,然后同步项目
implementation 'com.zfdang.multiple-images-selector:multiple-images-selector:1.1.5'
//因为是使用的Glide图片加载器显示的图片,所以还需要添加glide的依赖
implementation 'com.github.bumptech.glide:glide:3.7.0'
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
//下面两个权限是你想要在图片选择器中实现拍照所需的权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
	 ...
    android:name=".DemoApplication"
    ...
    
    <activity
        android:name="com.zfdang.multiple_images_selector.ImagesSelectorActivity"
        android:configChanges="orientation|screenSize"/>
    
</application>

当然了,Android6.0版本后,还需要手动添加程序运行时的读取相册权限,代码如下:

 //高版本手动获取权限
    public void myPermission() {
        int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    this,
                    PERMISSIONS_STORAGE,
                    IMAGE_OPEN
            );
        }
    }

    //申请回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull  String[] permissions, @NonNull  int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case IMAGE_OPEN:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED) {
                    isGreen = false;
                } else {
                    isGreen = true;
                }
                break;
        }
    }
  1. 应用初始化
public class DemoApplication extends Application
{
	@Override
	public void onCreate() {
    super.onCreate();

    // the following line is important
    Fresco.initialize(getApplicationContext());
	}
}

以上就是我在公司项目中使用的多图选择器的一种原生框架,相对来说比较简单易理解,适合初级开发者,该框架github的源码文档也给大家看一下吧:点击此处进入传送门

当然android中并不是只有这一种框架的,接下来继续介绍吧:

Matisse图片选择器的使用详解
一、简介

  • 简单容易上手
  • 支持日夜间模式,可以自定义主题
  • 自定义选中图片的最大数
  • JPEG, PNG, GIF 图片类型的显示
  • 支持有序选择图片,也即选择图片的时候会有 1, 2, 3, 4… 样式的 CheckBox;
  • 支持自定义筛选,完全自定义筛选规则
  • 可以定义图片缩略图的缩放比例。
  • 支持横竖屏。Matisse 做了状态保存的工作
  • 支持不同的图片加载库,目前支持 Glide 和 Picasso

二、使用步骤
1、 添加依赖
build.gradle文件中代码:

repositories {
    jcenter()
}
dependencies {
    compile 'com.zhihu.android:matisse:0.5.0-alpha4'
    compile 'com.github.bumptech.glide:glide:3.7.0'
}

2、添加相关权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
//android6.0版本权限申请要求同上multiple-images-selector多图选择器

3、启动选择器

如果你不需要点击拍照,而且也对过滤没有要求的话就可以直接使用了
intent跳转到MatisseActivity从你当前的Activity或者Fragment

基本使用方式
1.定义常量

private static final int REQUEST_CODE_CHOOSE = 23;//定义请求码常量

2.启动MatisseActivity

Matisse  
.from(MainActivity.this)
.choose(MimeType.allOf())//照片视频全部显示
.countable(true)//有序选择图片
.maxSelectable(9)//最大选择数量为9
.gridExpectedSize(120)//图片显示表格的大小getResources()
        .getDimensionPixelSize(R.dimen.grid_expected_size)
.restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)//图像选择和预览活动所需的方向。
.thumbnailScale(0.85f)//缩放比例
.theme(R.style.Matisse_Zhihu)//主题  暗色主题 R.style.Matisse_Dracula
.imageEngine(new GlideEngine())//加载方式
.forResult(REQUEST_CODE_CHOOSE);//请求码

3.接受选择的结果

  List<Uri> mSelected;
@Override      //接收返回的地址
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_CHOOSE && resultCode == RESULT_OK) {
        mSelected = Matisse.obtainResult(data);
        Log.d("Matisse", "mSelected: " + mSelected);
    }
}

当然如果大家想要试试实现拍照和过滤器的话,可以参考这位大牛的博客,(点击有惊喜)

好啦,最后来看一下运行效果吧:

图片选择器运行效果

好了,以上就是本篇文章的内容,都是android的原生框架,会用就可以了,懂逻辑就行,当然我做的介绍也是很简单易懂的,因为只是去实现选择图片,然后把图片显示出来,逻辑好理解,当然如果大家想要进一步探讨对图片的加工处理,裁剪等,可以参考一下:点击进入新世界

隔了那么长时间再次写博客,居然有点手生了,要尽快熟悉起来呀!!!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-11 12:31:59  更:2021-08-11 12:33:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 7:31:06-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码