Android仿朋友圈发布动态

2020-11-09  本文已影响0人  重拾丢却的梦

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

1. 效果图

2.gif

2. 实现思路

最终目标:

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

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

实现的大体步骤:

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.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 出现的问题

完成后效果如下


1.gif

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

解决方法:

更改完的效果如下

2.gif

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. 总结

注意事项:

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

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

6. 参考文章

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

Matisse:Github

上一篇 下一篇

猜你喜欢

热点阅读