简介

模拟微信朋友圈九宫格图片选取,实现添加、预览、展示、删除等操作,并对选取条件进行自定义限制。

效果展示




流程图

代码示例

build.gradle(app)

implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0' //图片选择器

SelectPlotAdapter

package com.sci99.mtd_baselib_demo.adapter.uploadimport android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.sci99.mtd_baselib_demo.R
import com.sci99.mtd_baselib_demo.utils.Tools/*** Created by liubomin on 2022/11/17** @author liubomin*/class SelectPlotAdapter(val context: Context, private val picMax: Int, val callback: CallbackListener) : RecyclerView.Adapter<SelectPlotAdapter.SelectHolder>() {private var mediaDtoList = mutableListOf<String>()override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SelectHolder {return SelectHolder(LayoutInflater.from(context).inflate(R.layout.item_image_upload, parent, false))}override fun onBindViewHolder(holder: SelectHolder, position: Int) {if (position >= mediaDtoList.size && position < picMax) {Tools.showGlide(context, holder.gallery, "");holder.delete.visibility = View.GONE} else {Tools.showGlide(context, holder.gallery, mediaDtoList[position])holder.delete.visibility = View.VISIBLE}holder.delete.setOnClickListener {callback.delete(position)}holder.gallery.setOnClickListener {//添加新图片点击事件if (position >= mediaDtoList.size && position <= picMax - 1) {callback.add()} else {//点击查看图片事件callback.item(position)}}}override fun getItemCount(): Int {return if (mediaDtoList.size == 0) {1} else {if (mediaDtoList.size >= picMax) picMax else mediaDtoList.size + 1}}class SelectHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {val gallery: ImageView = itemView.findViewById(R.id.iv_show_gallery)val delete: ImageView = itemView.findViewById(R.id.iv_delete)}interface CallbackListener {fun add()fun delete(position: Int)fun item(position: Int)}@SuppressLint("NotifyDataSetChanged")fun setImageList(mList: MutableList<String>) {this.mediaDtoList = mListnotifyDataSetChanged()}
}

NineImageUploadActivity

package com.sci99.mtd_baselib_demo.activity.ui.image.uploadimport android.content.Intent
import android.os.Build
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.luck.picture.lib.PictureSelector
import com.luck.picture.lib.config.PictureConfig
import com.luck.picture.lib.entity.LocalMedia
import com.sci99.mtd_baselib_demo.R
import com.sci99.mtd_baselib_demo.adapter.upload.SelectPlot2Adapter
import com.sci99.mtd_baselib_demo.databinding.ActivityNineImageUploadBinding
import com.sci99.mtd_baselib_demo.utils.Tools
import com.zs.base_library.base.BaseNoModelActivity/*** Created by liubomin on 2022/11/17** @author liubomin*/
class NineImageUploadActivity : BaseNoModelActivity<ActivityNineImageUploadBinding>() {private lateinit var adapter: SelectPlotAdapterprivate var allSelectList = mutableListOf<String>() //所有的图片路径集合private var selectList = mutableListOf<LocalMedia>() //图片选择器返回的集合private val picMax = 9 //最大图片选择数override fun onCreate(): Int {return R.layout.activity_nine_image_upload}override fun initView() {initAdapter()}/*** 初始化适配器*/private fun initAdapter() {adapter = SelectPlotAdapter(context, picMax, object : SelectPlotAdapter.CallbackListener {override fun add() {Tools.checkPermission(context){Tools.galleryPictures(this@NineImageUploadActivity, picMax, selectList)}}override fun delete(position: Int) {allSelectList.removeAt(position)selectList.removeAt(position)adapter.setImageList(allSelectList)}override fun item(position: Int) {//图片选择器自带预览PictureSelector.create(this@NineImageUploadActivity).themeStyle(R.style.picture_default_style).isWeChatStyle(true).imageEngine(GlideEngine.createGlideEngine()) // 选择器展示不出图片则添加.openExternalPreview(position, selectList)}})val layoutManager = GridLayoutManager(this, 3, RecyclerView.VERTICAL, false)binding.rvImage.layoutManager = layoutManageradapter.setImageList(allSelectList)binding.rvImage.adapter = adapter}/***图片选择结果的回调*/override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)if (resultCode == RESULT_OK) {when (requestCode) {PictureConfig.CHOOSE_REQUEST -> {selectList.clear()selectList = PictureSelector.obtainMultipleResult(data)showSelectPic(selectList)}}}}/*** 展示所选择的图片*/private fun showSelectPic(selectList: List<LocalMedia>) {allSelectList.clear()selectList.forEachIndexed { index, _ ->//判断是否10.0以上val path = if (Build.VERSION.SDK_INT >= 29) {selectList[index].androidQToPath} else {selectList[index].path}allSelectList.add(path)}adapter.setImageList(allSelectList)}
}

Tools

package com.sci99.mtd_baselib_demo.utilsimport android.app.Activity
import com.bumptech.glide.Glide
import android.content.Context
import android.os.Build
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.load.resource.bitmap.CenterInside
import com.bumptech.glide.request.RequestOptions
import com.luck.picture.lib.config.PictureConfig
import com.sci99.mtd_baselib_demo.activity.ui.image.upload.GlideEngine
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.PictureSelector
import com.hjq.permissions.OnPermission
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.luck.picture.lib.entity.LocalMedia
import com.sci99.mtd_baselib_demo.R
import com.zs.base_library.utils.toastobject Tools {/*** 检查权限*/fun checkPermission(context: Context, go: () -> Unit) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {go()} else {XXPermissions.with(context as Activity).permission(Permission.Group.STORAGE) //不指定权限则自动获取清单中的危险权限.request(object : OnPermission {override fun hasPermission(granted: List<String?>?, isAll: Boolean) {if (isAll) {go()}}override fun noPermission(denied: List<String?>?, quick: Boolean) {toast("请允许申请权限,才能执行本次操作")}})}}/*** 打开图库*/fun openGallery(activity: AppCompatActivity?, maxSize: Int) {PictureSelector.create(activity).openGallery(PictureMimeType.ofImage()) //全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()//.theme()//主题样式(不设置为默认样式) 也可参考demo values/styles下 例如:R.style.picture.white.style.maxSelectNum(maxSize) // 最大图片选择数量 int.minSelectNum(1) // 最小选择数量 int.imageSpanCount(3) // 每行显示个数 int.imageEngine(GlideEngine.createGlideEngine()) //.selectionMode()// 多选 or 单选 PictureConfig.MULTIPLE or PictureConfig.SINGLE//.isPreviewImage(true)// 是否可预览图片 true or false//.isPreviewVideo()// 是否可预览视频 true or false//.freeStyleCropEnabled() // 是否可播放音频 true or false.isCamera(false) // 是否显示拍照按钮 true or false//.imageFormat(PictureMimeType.PNG)// 拍照保存图片格式后缀,默认jpeg.isZoomAnim(true) // 图片列表点击 缩放效果 默认true//.setOutputCameraPath("/CustomPath")// 自定义拍照保存路径,可不填.isEnableCrop(true) // 是否裁剪 true or false//.isCompress(true)// 是否压缩 true or false//.withAspectRatio()// int 裁剪比例 如16:9 3:2 3:4 1:1 可自定义//.hideBottomControls()// 是否显示uCrop工具栏,默认不显示 true or false//.isGif(false)// 是否显示gif图片 true or false//.compressSavePath(getPath())//压缩图片保存地址.freeStyleCropEnabled(true) // 裁剪框是否可拖拽 true or false//.circleDimmedLayer()// 是否圆形裁剪 true or false//.showCropFrame()// 是否显示裁剪矩形边框 圆形裁剪时建议设为false   true or false//.showCropGrid()// 是否显示裁剪矩形网格 圆形裁剪时建议设为false    true or false//.isOpenClickSound(false)// 是否开启点击声音 true or false//.selectionData()// 是否传入已选图片 List<LocalMedia> list//.isPreviewEggs()// 预览图片时 是否增强左右滑动图片体验(图片滑动一半即可看到上一张是否选中) true or false//.cutOutQuality(90)// 裁剪压缩质量 默认90 int.minimumCompressSize(100) // 小于100kb的图片不压缩//.synOrAsy(true)//同步true或异步false 压缩 默认同步//.cropImageWideHigh()// 裁剪宽高比,设置如果大于图片本身宽高则无效 int//.rotateEnabled(true) // 裁剪是否可旋转图片 true or false.scaleEnabled(true) // 裁剪是否可放大缩小图片 true or false//.videoQuality()// 视频录制质量 0 or 1 int//.videoMaxSecond(15)// 显示多少秒以内的视频or音频也可适用 int//.videoMinSecond(10)// 显示多少秒以内的视频or音频也可适用 int//.recordVideoSecond()//视频秒数录制 默认60s int.forResult(PictureConfig.CHOOSE_REQUEST) //结果回调onActivityResult code}/*** 打开拍照*/fun takingPictures(activity: AppCompatActivity?) {PictureSelector.create(activity).openCamera(PictureMimeType.ofImage()).forResult(PictureConfig.REQUEST_CAMERA)}/*** 打开图库+拍照按钮*/fun galleryPictures(activity: AppCompatActivity?, maxSize: Int, selectList: MutableList<LocalMedia>) {PictureSelector.create(activity).openGallery(PictureMimeType.ofImage()) //全部.PictureMimeType.ofAll()、图片.ofImage()、视频.ofVideo()、音频.ofAudio()//.theme()//主题样式(不设置为默认样式) 也可参考demo values/styles下 例如:R.style.picture.white.style.maxSelectNum(maxSize) // 最大图片选择数量 int.selectionData(selectList).minSelectNum(1) // 最小选择数量 int.imageEngine(GlideEngine.createGlideEngine()).imageSpanCount(3) // 每行显示个数 int.isCamera(true) // 是否显示拍照按钮 true or false.isZoomAnim(true) // 图片列表点击 缩放效果 默认true//.isEnableCrop(true)// 是否裁剪 true or false.isCompress(true) // 是否压缩 true or false.minimumCompressSize(100) // 小于100kb的图片不压缩.forResult(PictureConfig.CHOOSE_REQUEST) //结果回调onActivityResult code}/*** 加载图片(圆角)** @param context 上下文* @param view    图片控件* @param url     网络图片地址*/fun showGlide(context: Context, view: ImageView, url: String?) {val options: RequestOptions = RequestOptions()
//            .transform(GlideRoundTransform(context, 5))//圆角.transform(CenterInside())Glide.with(context).load(url).apply(options).placeholder(R.drawable.add_picture).into(view)}}

activity_nine_image_upload

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"><data></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.sci99.mtd_baselib_demo.utils.CustomTitleBar1android:layout_width="match_parent"android:layout_height="48dp"app:text="图片选择" /><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请详细描述您的问题,本窗口仅记录问题,并不提交。"android:padding="15dp"android:textColor="@color/color_grey_999999"android:textSize="15sp" /><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/rv_image"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="80dp"android:paddingLeft="15dp"android:paddingRight="5dp" /></LinearLayout>
</layout>

item_image_upload

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="data"type="String" /></data><RelativeLayoutandroid:layout_width="100dp"android:layout_height="100dp"android:layout_marginRight="5dp"android:layout_marginBottom="5dp"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_show_gallery"android:layout_width="match_parent"android:layout_height="match_parent"imageUrl="@{data}"imagePlaceholder="@{@drawable/add_picture}"android:src="@drawable/add_picture"android:scaleType="centerCrop" /><ImageViewandroid:id="@+id/iv_delete"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentEnd="true"android:paddingStart="5dp"android:paddingBottom="5dp"android:src="@drawable/ic_delete" /></RelativeLayout>
</layout>

版本适配

implementation 'com.github.LuckSiege.PictureSelector:picture_library:v2.5.8' //图片选择器

第三方库2.5.8版本与Android11及以上版本不适配,会出现以下相册空白现象

sdk为31

PictureSelector三方库

3.0
相关更多文档请点击

PictureSelector九宫格图片展示相关推荐

  1. Android微信九宫格图片展示控件

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/214 Android微信九宫格图片展示控件 半年前,公司产 ...

  2. 模仿微信九宫格图片展示控件

    主题 仿微信九宫格图片展示控件 github地址:点击打开链接 使用方法以及源码都在github上面

  3. android从九宫格全屏预览,仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图...

    AssNineGridView 仿微信朋友圈展示图片的九宫格图片展示控件,支持点击图片全屏预览大图(可自定义). 写在前面 这是一个九宫格控件,本来是很久之前就写好了,现在才开源出来,也是看了很多优秀 ...

  4. Android 九宫格图片展示的实现

    添加图片效果图: 添加满 9 张图片效果图: 添加文件相关文章:<图片操作框架 TakePhoto 的引入> 长按删除图片效果图: 删除弹窗相关文章:<常用代码整理:Android ...

  5. Android自定义九宫格图片展示,类似微信朋友圈

    之前网上也找了很多类似的功能,但是很多放在列表中复用item就出现高度测量是0,出现条目中图片空间不显示问题 这里做了一些优化,解决该问题 具体可参考这篇博客,(这里要感谢博主)不过这个放在列表复用时 ...

  6. html 实现格子效果图,css 实现的九宫格图片展示

    朋友圈.微博的图片展示会根据数量不同而样式不同,这也可以用纯css实现.在<css揭秘>中,根据兄弟元素的数量来设置样式讲到的技巧就可以解决这个问题. 我们知道css中有一些跟子元素排序相 ...

  7. android朋友圈评论功能兼容沉浸式状态栏,九宫格图片显示

    android朋友圈评论功能,沉浸式状态栏,九宫格图片显示器,上拉加载下拉刷新功能,可直接用到项目中 背景 在前两个项目开发过程中用到了朋友圈这个功能,包含了评论回复.九宫格图片及大图展示展示,上拉加 ...

  8. python语言编写一个生成九宫格图片的代码_用Python一键生成炫酷九宫格图片,火了朋友圈...

    作为一个男同胞来说,为了给女朋友拍一张美美的照片,着实需要花费很大的时间和精力,不仅仅需要从众多的图片中精心挑选,而且还需要有着超强的图片精修能力,才能得到一张张达到女友要求的图片,真心不容易啊- 朋 ...

  9. python把一堆图片分成n份,用Python一键生成炫酷九宫格图片,火了朋友圈

    原标题:用Python一键生成炫酷九宫格图片,火了朋友圈 作为一个男同胞来说,为了给女朋友拍一张美美的照片,着实需要花费很大的时间和精力,不仅仅需要从众多的图片中精心挑选,而且还需要有着超强的图片精修 ...

最新文章

  1. 告别2019,展望2020:让我们看一看这十年中深度学习的经典瞬间
  2. 无法消除恐惧?Nature发现肠道菌与大脑间更多的神秘联系...
  3. linux的简单面试题,收集的一些简单的UNIX/Linux面试题
  4. Day 31 并发编程
  5. Markdown:数学公式练习(3)
  6. 自认为有必要学习的Sql 总结,积累 mybatis
  7. android 无appid分享_App ID 和Bundle ID 有什么不同?ios面试攻克篇(六)
  8. 博客园是个大金矿,管理员不挖掘有些可惜:给博客园提一些双赢的建议
  9. Linux和Windows下部署BeetleX服务网关
  10. oracle创建、删除索引等操作
  11. win10操做系统恢复操做
  12. JavaWeb知识总结
  13. python的第三方库是干什么用的-Python 常用的标准库以及第三方库有哪些?
  14. pagehelper Jar包下载
  15. 阿里大佬手把手教你用jmeter做压力测试(详图)
  16. Openwrt源码LuCI应用完整说明
  17. 利用Power BI制作分级地图报表
  18. 数电课设交通灯控制器
  19. MYSQL的字符串支持保存表情,比如微信表情
  20. iOS内嵌unity

热门文章

  1. Z3735d android x86,首款搭载Z3735处理器 神秘平板被曝光
  2. android 全屏广告,手机端全屏广告展示问题
  3. 商务口语 - 意见分歧话题
  4. docker exec -it container1 /bin/bash 异常
  5. 详解:大数据分析的学习之路
  6. html追加没有样式,html中append追加的表格元素和静态显示的元素样式不同?
  7. redis恢复阿里云rdb文件
  8. Android系统(手机平板)根目录详解
  9. python加数据库_python向数据库添加数据(添加一条数据)
  10. C# TSC TE244 PrintDocument 固定资产哑银不干胶标签打印