• Android一对一直播系统源码开发,仿朋友圈发布动态的实现


    在一对一直播系统源码开发中,为了优化用户的社交体验,会开发很多功能,其中动态发布功能充分满足了用户的非实时性社交需求,像朋友圈那样的发布动态流程是非常符合人们使用习惯的,所以在一对一直播系统源码开发时,也可以实现仿朋友圈发布动态。

    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设置隐藏,否则就显示,这样就可以实现加号布局的显示隐藏效果

    1. 具体实现
      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.VISIBLE
                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)
            }
        }
    }
    
    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 = 1
        val PIC_ITEM = 2
        private var onItemClickListener: OnItemClickListener? = null
    
        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)
                }
            }
        }
    
        /**
         * 当数量小于最大值时,返回的数量+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进行更改。
    Android一对一直播系统源码开发,仿朋友圈发布动态的实现做下来想想过程,其实还算是比较简单的,搞清楚里面的逻辑,其实就是用到了Recyclerview的Adapter的多布局,有了基础功能,图片的点击或者长按删除等效果都可以做。

    本文转载自网络,转载仅为分享干货知识,如有侵权欢迎联系云豹科技进行删除处理
    原文链接:https://www.jianshu.com/p/f48c266d5ee9

  • 相关阅读:
    Sql2000分页效率
    CSS笔记
    向模态窗体传递参数和获取返回值
    css 实现div 内容垂直居中
    轻量级的数据交换格式——初识Json
    CSS 绝对定位
    前台小模块CSS布局代码
    XML常用类(淘宝API)
    表单form
    js 分页
  • 原文地址:https://www.cnblogs.com/yunbao/p/14973029.html
Copyright © 2020-2023  润新知