Android仿微信朋友圈发布动态

news/2024/10/18 20:19:56/

有一年没发表文章了,语言都从java换为kotlin了。最近还是做了不少东西的,后面再慢慢更新吧,还是代码能带给人快乐

1. 效果图

在这里插入图片描述

2. 实现思路

最终目标:

  • 没有数据时,显示加号布局,选择图片达到最大值时,加号布局隐藏,当删掉一张图片后,加号布局又显示出来

里面用到的图片选择框架是知乎的matisse,图片加载是glide,权限申请是permissionx,具体的使用就不详细说明了,若有需要日后再单独出篇文章。

这里主要讲图片选择后recyclerview里加号布局的显示与隐藏,这里用到了recyclerview多布局实现

实现的大体步骤:

  • 重写Adapter的getItemCount()方法,返回值为data.size+1,这里的data是所选图片集合,这样就可以无论有没有数据,都给加号布局留下位置。

  • 重写getItemViewType()方法,当position+1=getItemCount()时,返回加号布局,否则返回图片布局。利用recyclerview的多布局,来实现加号布局和图片布局的切换。

    实现原理:因为position是从0开始计数,而getItemCount()因为我们返回data.size+1,所以是从1开始计数,当data没有数据时,position为0,而getItemCount()是1,此时position+1=getItemCount(),所以显示加号布局。当data有数据,假设为2张时,getItemCount()为3,position即下标为0,1时,显示图片布局,而position为2时,因为2+1=3,所以显示加号布局

  • 重写onBindViewHolder()方法,当holder是加号的Holder时,判断data.size,当它>=最大值时,holder.itemView设置隐藏,否则就显示,这样就可以实现加号布局的显示隐藏效果

4. 具体实现

4.1 创建适配器

class MyCommonAdapter(private val data: MutableList<String>,private val maxNum: Int) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {//加号布局val ADD_ITEM = 1//图片布局val PIC_ITEM = 2
}

4.2 创建多布局viewHolder

//加号布局
inner class AddViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)//普通布局
inner class PicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {val pic: ImageView = itemView.findViewById(R.id.ivImage)val del: ImageView = itemView.findViewById(R.id.ivDelete)
}

4.3 重写getItemViewType和getItemCount方法

/**
* 如果当前位置+1=itemCount,则代表它是最后一个,因为位置是从0计数的,而itemCount是从1计数
*/
override fun getItemViewType(position: Int): Int {return if (position + 1 == itemCount) {ADD_ITEM} else {PIC_ITEM}
}
/**
* 返回的数量+1,为了给加号布局添加位置
*/
override fun getItemCount(): Int {return data.size + 1
}

4.4 创建和绑定布局

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {when (viewType) {ADD_ITEM -> {var view =LayoutInflater.from(parent.context).inflate(R.layout.add_item, parent, false)return AddViewHolder(view)}else -> {var view = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)return PicViewHolder(view)}}
}override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {//加号的布局if (holder is AddViewHolder) {//增加的布局if (data.size >= maxNum) {holder.itemView.visibility = View.GONE} else {holder.itemView.visibility = View.VISIBLEholder.itemView.setOnClickListener {onItemClickListener?.onItemAddClick(position)}}}//加载图片的布局else {Glide.with(holder.itemView.context).load(data[position]).into((holder as PicViewHolder).pic)holder.pic.setOnClickListener {onItemClickListener?.onItemPicClick(position)}holder.del.setOnClickListener {onItemClickListener?.onItemDelClick(position)}}
}interface OnItemClickListener {//点击增加按键fun onItemAddClick(position: Int)//点击删除按键fun onItemDelClick(position: Int)//点击图片fun onItemPicClick(position: Int)
}

4.5 出现的问题

完成后效果如下

在这里插入图片描述

你仔细观察,会出现当选完6个后,确实加号布局隐藏掉了,但是,由于getItemCount()返回的是data.size()+1,尽管隐藏掉了,但是还是会多出来一个加号的布局位置,如同所示,那该如何解决这个问题呢

解决方法:

  • getItemCount()方法,当data.size()达到最大值时,返回data.size(),当没有达到最大值时,返回data.size()+1

  • getItemCount()方法,当data.size()达到最大值时,getItemViewType()返回图片布局,当没有达到时,按照原先的判断逻辑如果position+1=getItemCount()则返回添加布局,否则返回图片布局

  • 如此,就可以取消掉onBindViewHolder()里面当data.size达到最大值后对加号布局隐藏的操作逻辑了

更改完的效果如下

在这里插入图片描述

4.6 完整代码

class MyCommonAdapter(private val data: MutableList<String>,private val maxNum:Int) :RecyclerView.Adapter<RecyclerView.ViewHolder>() {val ADD_ITEM = 1val PIC_ITEM = 2private var onItemClickListener: OnItemClickListener? = nulloverride fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {when (viewType) {ADD_ITEM -> {var view =LayoutInflater.from(parent.context).inflate(R.layout.add_item, parent, false)return AddViewHolder(view)}else -> {var view = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)return PicViewHolder(view)}}}/*** 当数量小于最大值时,返回的数量+1,为了给加号布局添加位置* 否则就返回正常的数据大小(达到最大值后,不用给加号布局添加位置)*/override fun getItemCount(): Int {return if(data.size<maxNum){data.size+1}else{data.size}}override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {//加号的布局if (holder is AddViewHolder) {holder.itemView.setOnClickListener {onItemClickListener?.onItemAddClick(position)}}//加载图片的布局else {Glide.with(holder.itemView.context).load(data[position]).into((holder as PicViewHolder).pic)holder.pic.setOnClickListener {onItemClickListener?.onItemPicClick(position)}holder.del.setOnClickListener {onItemClickListener?.onItemDelClick(position)}}}/*** 当数量达到最大值时,返回图片布局* 否则,如果当前位置+1=itemCount,则代表它是最后一个,因为位置是从0计数的,而itemCount是从1计数*/override fun getItemViewType(position: Int): Int {if(data.size==maxNum){return PIC_ITEM}else{return if (position + 1 == itemCount) {ADD_ITEM} else {PIC_ITEM}}}//加号布局inner class AddViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)//普通布局inner class PicViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {val pic: ImageView = itemView.findViewById(R.id.ivImage)val del: ImageView = itemView.findViewById(R.id.ivDelete)}//设置接口回调来实现点击功能fun setOnMyClickListener(onClickListener: OnItemClickListener?) {onItemClickListener = onClickListener}interface OnItemClickListener {//点击增加按键fun onItemAddClick(position: Int)//点击删除按键fun onItemDelClick(position: Int)//点击图片fun onItemPicClick(position: Int)}
}

5. 总结

注意事项:

  • 因为android10及以上开始使用分区存储,简单的动态申请读取权限,可能会出现选择完照片后recyclerview里加载不出图片,因为获取不到,简单的做法是manifest中加入android:requestLegacyExternalStorage="true"属性,但是在android11上就已经失效,需要对matisse进行更改,具体做法可参考这篇文章:Matisse 图片库在 Android10 上拍照,预览问题

做下来想想过程,其实还算是比较简单的,搞清楚里面的逻辑,其实就是用到了Recyclerview的Adapter的多布局,有了基础功能,图片的点击或者长按删除等效果都可以做。

Github地址,如果对你有帮助的话还麻烦给个start

觉得不错还望老板打个赏呗,帮我买条秋裤穿 (*꒦ິ⌓꒦ີ)

6. 参考文章

android实现微信朋友圈发布动态功能

Matisse:Github


http://www.ppmy.cn/news/702490.html

相关文章

微信如何定时发朋友圈?一招教你解决

在人们依赖微信进行沟通、获取信息的同时&#xff0c;微信营销也不可避免&#xff0c;在微信朋友圈推广自己的产品或服务&#xff0c;成为至今最为火爆的一种营销方式。朋友圈营销的优势是信任&#xff0c;缺点是容易透支信任。 或许你发现了朋友圈的价值&#xff0c;也想从中…

微信应该怎么定时发送朋友圈~

微信怎么发朋友圈&#xff08;微信如何定时发朋友圈&#xff09;&#xff0c;很多情况下&#xff0c;我们都会遇到定时发文的情况&#xff0c;对于我们来说&#xff0c;定时发文很简单。 只要将文案编辑好&#xff0c;使用平台的定时发文功能就可以&#xff0c;所以&#xff0…

微信朋友圈服务器缓存,如何找到微信朋友圈照片缓存

朋友圈里有些朋友会发些很重要的照片&#xff0c;可是一转眼想再去看&#xff0c;却发现被删除了。这种情况下还有办法找到么?下面是学习啦小编给大家整理的一些有关找到微信朋友圈照片缓存的方法&#xff0c;希望对大家有帮助! 找到微信朋友圈照片缓存的方法 将手机与电脑连接…

微信怎么屏蔽他人的朋友圈?图文教学,1分钟学会

有很多小伙伴在生活中和朋友有可能因为一些事情发生了争吵&#xff0c;在刷微信朋友圈的时候&#xff0c;老是刷到争吵朋友的消息。微信怎么屏蔽他人的朋友圈&#xff1f;其实答案很简单&#xff0c;只需要几步简单的设置就可以完成&#xff0c;一起跟小编来看看吧。 微信怎么屏…

微信朋友圈api接口调用源码

微信朋友圈api接口&#xff0c;推送微信朋友圈、发朋友圈 /** * 触发推送朋友圈列表 * author wechatno:tangjinjinwx * startTime传秒 * blog http://www.wlkankan.cn */ Async public void handleMsg(ChannelHandlerContext ctx, Tra…

微信朋友圈服务器缓存,怎么删微信朋友圈缓存?

怎么删微信朋友圈缓存?各位微信用户&#xff0c;如果你的微信软件使用久了以后&#xff0c;微信就会用起来卡一点&#xff0c;这个是时候就要去清理微信缓存了哦&#xff0c;那么应该怎么删微信朋友圈缓存呢?以下是方法了哦。 怎么删微信朋友圈缓存? 如果要删微信朋友圈缓存…

微信小程序分享朋友圈API限制问题

在开发微信小程序过程中&#xff0c;需要实现将小程序分享到朋友圈&#xff0c;以扩大宣传范围&#xff0c;吸引流量。 实现也不难&#xff0c;满足【两个条件】即可&#xff1a; 首先&#xff0c;页面需设置允许“发送给朋友”。具体参考 Page.onShareAppMessage 接口文档 满…

Python读取微信朋友圈

未进行可&#xff0c;严禁转载 文章目录 背景法1&#xff0c;不适用法2&#xff0c;已不能用法3&#xff1a;Appnium法4&#xff1a;模拟操作整体代码后续工作及扩展 背景 由于课题需要爬取朋友圈的内容作为研究数据&#xff0c;稍微研究了一下。 目前爬取有四种方法&#xf…