RecyclerView-BRVAH第三方框架

RecyclerView其实都已经用了一段时间了,但是说实话,我是真的不太熟悉,而且看到自己项目用的这个BRVAH框架后,就觉得很神奇,因为之前不是刚学了下动画基础嘛,然后就想到处去实践,后来大佬就说这个框架很好用的,于是我就开始研究起来了,但是归根前提,还是简单说下RecyclerView的基础使用吧,这样也可以让小白们也看得懂,先附上最简单的用法哈:


截屏2020-11-13 下午10.32.09.png

看了这个之后是不是觉得还是挺好实现,哦哦,还有代码!!附上啦:
MyRecyclerViewAdapte,而ViewHolder作为内部类也写在里面了

import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.NonNull
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.example.concatadapter.MyRecyclerViewAdapter.MyViewHolder
import java.util.*

/**
 * 1、继承RecyclerView.Adapter
 * 2、绑定ViewHolder
 * 3、实现Adapter的相关方法
 */
class MyRecyclerViewAdapter(private val mContext: Context, recyclerView: RecyclerView) : RecyclerView.Adapter() {
    private var onItemClickListener: OnItemClickListener? = null
    private val mRv: RecyclerView
    private var dataSource: MutableList
    private var addDataPosition = -1
    fun setOnItemClickListener(onItemClickListener: OnItemClickListener?) {
        this.onItemClickListener = onItemClickListener
    }

    fun setDataSource(dataSource: MutableList) {
        this.dataSource = dataSource
        notifyDataSetChanged()
    }

    /**
     * ViewHolder 绑定数据
     * @param myViewHolder
     * @param position
     */
    override fun onBindViewHolder(@NonNull myViewHolder: MyViewHolder, position: Int) {
        myViewHolder.mIv.setImageResource(getIcon(position))
        myViewHolder.mTv.text = dataSource[position]
        /**
         * 只在瀑布流布局中使用随机高度
         */
        if (mRv.layoutManager?.javaClass=== StaggeredGridLayoutManager::class.java) {
            val params =
                LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, randomHeight)
            myViewHolder.mTv.layoutParams = params
        } else {
            val params = LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            )
            myViewHolder.mTv.layoutParams = params
        }

//        改变ItemView背景颜色
        if (addDataPosition == position) {
            myViewHolder.mItemView.setBackgroundColor(Color.RED)
        } else {
            myViewHolder.mItemView.setBackgroundColor(Color.parseColor("#A4D3EE"))
        }
        myViewHolder.mItemView.setOnClickListener { //                调用接口的回调方法
            if (onItemClickListener != null) {
                onItemClickListener!!.onItemClick(position)
            }
        }
    }

    /**
     * 返回数据数量
     * @return
     */
    override fun getItemCount(): Int {
        return dataSource.size
    }

    private fun getIcon(position: Int): Int {
        when (position % 5) {
            0 -> return R.mipmap.a
            1 -> return R.mipmap.b
            2 -> return R.mipmap.c
            3 -> return R.mipmap.d
            4 -> return R.mipmap.e
        }
        return 0
    }

    /**
     * 返回不同的ItemView高度
     * @return
     */
    private val randomHeight: Int
         get() = (Math.random() * 1000).toInt()

    /**
     * 添加一条数据
     * @param position
     */
    fun addData(position: Int) {
        addDataPosition = position
        dataSource.add(position, "插入的数据")
        notifyItemInserted(position)

//        刷新ItemView
        notifyItemRangeChanged(position, dataSource.size - position)
    }

    /**
     * 删除一条数据
     * @param position
     */
    fun removeData(position: Int) {
        addDataPosition = -1
        dataSource.removeAt(position)
        notifyItemRemoved(position)

//        刷新ItemView
        notifyItemRangeChanged(position, dataSource.size - position)
    }

    inner class MyViewHolder(@NonNull itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var mItemView: View = itemView
        var mIv: ImageView = itemView.findViewById(R.id.iv)
        var mTv: TextView = itemView.findViewById(R.id.tv)

    }

    /**
     * ItemView点击事件回调接口
     */
    interface OnItemClickListener {
        fun onItemClick(position: Int)
    }

    init {
        dataSource = ArrayList()
        mRv = recyclerView
    }

    /**
     * 创建并且返回ViewHolder
     * @param
     * @param
     * @return
     */
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        return MyViewHolder(
            LayoutInflater.from(mContext).inflate(R.layout.item_layout, parent, false)
        )
    }
}

逻辑执行部分:

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.*
import java.util.*

class MainActivity : AppCompatActivity() {
    private var mRecyclerView: RecyclerView? = null
    private var mAdapter: MyRecyclerViewAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mRecyclerView = findViewById(R.id.recycler_view)

        // 线性布局
        val linearLayoutManager = LinearLayoutManager(this)
        //        横向排列ItemView
//        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//       数据反向展示
//        linearLayoutManager.setReverseLayout(true);
        mRecyclerView?.layoutManager = linearLayoutManager
        mAdapter = MyRecyclerViewAdapter(this, mRecyclerView!!)
        mRecyclerView?.adapter = mAdapter
        mRecyclerView?.itemAnimator = DefaultItemAnimator()

//        itemView点击事件监听
        mAdapter?.setOnItemClickListener(object : MyRecyclerViewAdapter.OnItemClickListener{
            override fun onItemClick(position: Int) {
                Toast.makeText(this@MainActivity, "第" + position + "数据被点击", Toast.LENGTH_SHORT).show()
            }
        })
    }

    /**
     * 添加数据
     * @param
     */
    fun onAddDataClick(view: View) {
        val data: MutableList = ArrayList()
        for (i in 0..19) {
            val s = "第" + i + "条数据"
            data.add(s)
        }
        mAdapter?.setDataSource(data)
    }

    /**
     * 切换布局
     * @param
     */
    fun onChangeLayoutClick(view: View) {
//        从线性布局 切换为 网格布局
        when {
            mRecyclerView?.layoutManager?.javaClass === LinearLayoutManager::class.java -> {
    //            网格布局
                val gridLayoutManager = GridLayoutManager(this, 2)
                mRecyclerView?.layoutManager = gridLayoutManager
            }
            mRecyclerView?.layoutManager?.javaClass === GridLayoutManager::class.java -> {
    //            瀑布流布局
                val staggeredGridLayoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
                mRecyclerView?.layoutManager = staggeredGridLayoutManager
            }
            else -> {
                // 线性布局
                val linearLayoutManager = LinearLayoutManager(this)
                mRecyclerView?.layoutManager = linearLayoutManager
            }
        }
    }

    /**
     * 插入一条数据
     * @param
     */
    fun onInsertDataClick(view: View) {
        mAdapter?.addData(1)
    }

    /**
     * 删除一条数据
     * @param
     */
    fun onRemoveDataClick(view: View) {
        mAdapter?.removeData(1)
    }

}

emmm,好了,基本的RecyclerView就实现了!!
然后重点来了,我主要还是要说下BRVAH第三方框架,真的很好用,良心推荐!!!
github地址:https://github.com/CymChad/BaseRecyclerViewAdapterHelper
官方地址:https://www.jianshu.com/p/b343fcff51b0
我用这个框架主要是为了实现过渡动画添加和adapter组合!!!
代码都是官方GitHub里面的,只是因为我是小白,所以才在这里注释下了,各位客将就看下吧:

截屏2020-11-14 上午10.31.54.png

AnimationAdapter

import android.text.TextPaint
import android.text.style.ClickableSpan
import android.view.View
import android.widget.TextView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.data.DataServer
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.baserecyclerviewadapterhelper.utils.ClickableMovementMethod
import com.chad.baserecyclerviewadapterhelper.utils.SpannableStringUtils
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder

/**
 * 文 件 名: AnimationAdapter
 * 创 建 人: Allen
 * 创建日期: 16/12/24 15:33
 * 邮   箱: [email protected]
 * 修改时间:
 * 修改备注:
 */
class AnimationAdapter : BaseQuickAdapter(R.layout.layout_animation, DataServer.getSampleData(100)) {
     override fun convert(helper: BaseViewHolder, item: Status?) {
        when (helper.layoutPosition.rem(3)) {
            0 -> helper.setImageResource(R.id.img, R.mipmap.animation_img1)
            1 -> helper.setImageResource(R.id.img, R.mipmap.animation_img2)
            2 -> helper.setImageResource(R.id.img, R.mipmap.animation_img3)
            else -> {
            }
        }
        helper.setText(R.id.tweetName, "Hoteis in Rio de Janeiro")
        val msg = "\"He was one of Australia's most of distinguished artistes, renowned for his portraits\""
         //SpannableStringUtils这个就是另一个的知识点了,append可以把固定的内容拼接上,如果是想更换msg的里面内容的特定内容的字体颜色之类的话就用
         //SpannableStringUtils.append("landscapes and nedes").setClickSpan(clickableSpan).create()
         val msg1="landscapes and nedes"
        (helper.getView(R.id.tweetText) as TextView).text = SpannableStringUtils.getBuilder(msg).append(msg1).setClickSpan(clickableSpan).create()
        (helper.getView(R.id.tweetText) as TextView).movementMethod = ClickableMovementMethod.getInstance()
         //设置焦点
        (helper.getView(R.id.tweetText) as TextView).isFocusable = false
         //设置是否可点击
        (helper.getView(R.id.tweetText) as TextView).isClickable = false
         //设置是否可长按
        (helper.getView(R.id.tweetText) as TextView).isLongClickable = false
    }
    //设置点击时间
    private val clickableSpan: ClickableSpan = object : ClickableSpan() {
        override fun onClick(widget: View) {
            Tips.show("事件触发了 landscapes and nedes")
        }

        override fun updateDrawState(ds: TextPaint) {
            ds.color = context.resources.getColor(R.color.clickspan_color)
            //增加下划线,因为默认是没有下划线的
            ds.isUnderlineText = true
        }
    }
}

AnimationUseActivity

import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.baserecyclerviewadapterhelper.R
import com.chad.baserecyclerviewadapterhelper.adapter.AnimationAdapter
import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation1
import com.chad.baserecyclerviewadapterhelper.animator.CustomAnimation2
import com.chad.baserecyclerviewadapterhelper.entity.Status
import com.chad.baserecyclerviewadapterhelper.utils.Tips
import com.chad.library.adapter.base.BaseQuickAdapter
import com.jaredrummler.materialspinner.MaterialSpinner
import com.kyleduo.switchbutton.SwitchButton

/**
 * https://github.com/CymChad/BaseRecyclerViewAdapterHelper
 *
 *
 * modify by AllenCoder
 */
class AnimationUseActivity : AppCompatActivity() {
    private lateinit var mRecyclerView: RecyclerView
    private var mAnimationAdapter: AnimationAdapter? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_adapter_use)
        mRecyclerView = findViewById(R.id.rv_list)
        //setHasFixedSize 的作用就是确保尺寸是通过用户输入从而确保RecyclerView的尺寸是一个常数。RecyclerView 的Item宽或者高不会变。每一个Item添加或者删除都不会变。
        // 如果你没有设置setHasFixedSized没有设置的代价将会是非常昂贵的
        mRecyclerView.setHasFixedSize(true)
        mRecyclerView.layoutManager = LinearLayoutManager(this)
        initAdapter()
        initMenu()
        initView()
    }

    private fun initView() {
        val mImgBtn = findViewById(R.id.img_back)
        mImgBtn.setOnClickListener { finish() }
    }

    private fun initAdapter() {
        mAnimationAdapter = AnimationAdapter()
        //设置是否有动画效果
        mAnimationAdapter!!.animationEnable = true
        //Item中子项点击事件注册
        mAnimationAdapter!!.addChildClickViewIds(R.id.img, R.id.tweetName, R.id.tweetText)
        mAnimationAdapter!!.setOnItemChildClickListener { adapter, view, position ->
            var content: String? = null
            val status = adapter.getItem(position) as Status
            when (view.id) {
                R.id.img -> content = "img:" + status.userAvatar
                R.id.tweetName -> content = "name:" + status.userName
                R.id.tweetText -> content = "tweetText:" + status.userName
                else -> {
                }
            }
            //封装了Toast
            Tips.show(content)
        }
        mRecyclerView.adapter = mAnimationAdapter
    }

    private fun initMenu() {
        val spinner = findViewById(R.id.spinner)
        spinner.setItems("AlphaIn", "ScaleIn", "SlideInBottom", "SlideInLeft", "SlideInRight", "Custom1", "Custom2")
        spinner.setOnItemSelectedListener { _, position, _, _ ->
            when (position) {
                //透明度渐变,淡出淡入
                0 -> mAnimationAdapter!!.setAnimationWithDefault(BaseQuickAdapter.AnimationType.AlphaIn)
                //收缩效果
                1 -> mAnimationAdapter!!.setAnimationWithDefault(BaseQuickAdapter.AnimationType.ScaleIn)
                //底部弹出效果
                2 -> mAnimationAdapter!!.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInBottom)
                //左边弹出效果
                3 -> mAnimationAdapter!!.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInLeft)
                //右边弹出效果
                4 -> mAnimationAdapter!!.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInRight)
                //从顶层撞入安定的效果
                5 -> mAnimationAdapter!!.adapterAnimation = CustomAnimation1()
                //从左往右撞入安定的效果
                6 -> mAnimationAdapter!!.adapterAnimation = CustomAnimation2()
                else -> {
                }
            }
            mRecyclerView.adapter = mAnimationAdapter
        }
        //init firstOnly state
        //设置动画效果false为不限制,true为只显示一次
        mAnimationAdapter!!.isAnimationFirstOnly = false
        val switchButton = findViewById(R.id.switch_button)
        switchButton.setOnCheckedChangeListener { _, isChecked ->
            mAnimationAdapter!!.isAnimationFirstOnly = isChecked
            mAnimationAdapter!!.notifyDataSetChanged()
        }
    }
}

好啦!!其实官方里面说得真好清楚了,大家就继续研究吧!!!

你可能感兴趣的:(RecyclerView-BRVAH第三方框架)