ReclerView 常用布局及下拉刷新,点击item置顶操作

前言:

        很久之前,写了一篇关于ListView点击置顶操作的小笔记,后面一直由于自己目前在做测试相关的工作,也没有太多的时间来写RecyclerView点击置顶操作的笔记,特意抽空复习了一下,以此勉励自己,不能学了就忘,如有错误的地方,还请指正,谢谢

        recyclerView是比ListView功能更强大的一种布局,也更能随自己的心意来更改显示的样式,如ListView,GridView,瀑布流模型,多类型布局等,这也是比较常用的一些布局,废话不多说,开始看代码:

主活动

package com.example.a05_recyclerviewtestdemo

import android.annotation.SuppressLint
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.example.a05_recyclerviewtestdemo.adapter.GridViewAdapter
import com.example.a05_recyclerviewtestdemo.adapter.RecyclerViewAdapter
import com.example.a05_recyclerviewtestdemo.adapter.StaggerViewAdapter
import com.example.a05_recyclerviewtestdemo.base.BaseAdapter
import com.example.a05_recyclerviewtestdemo.bean.Fruit
import com.example.a05_recyclerviewtestdemo.utils.FruitData
import java.util.*
import javax.security.auth.callback.Callback
import javax.security.auth.callback.CallbackHandler
import kotlin.collections.ArrayList

class MainActivity : AppCompatActivity() {

    companion object{
        private const val TAG = "MainActivity"
        private lateinit var recyclerView:RecyclerView;
        private lateinit var fruits:ArrayList<Fruit>;
        private lateinit var adapter: BaseAdapter;
        @SuppressLint("StaticFieldLeak")
        private lateinit var swipeRefreshLayout: SwipeRefreshLayout
        private const val PULL_TO_FRESH = 1 //下拉刷新
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initData()
        showList(isVertical = true, isReverse = false)
        //监听刷新状态
        swipeRefreshListener()

        //添加分割线
        recyclerView.addItemDecoration(DividerItemDecoration(this))
    }

    @SuppressLint("ResourceAsColor")
    private fun swipeRefreshListener() {
        swipeRefreshLayout.setOnRefreshListener {
            handler.sendEmptyMessageDelayed(PULL_TO_FRESH, 3000)
        }
        swipeRefreshLayout.setColorSchemeColors(R.color.purple_500, R.color.purple_200, R.color.purple_700)
    }
    
    //模拟网络请求,子线程不能操作主线程,所以使用Handler来绘制UI
    private val handler:Handler = @SuppressLint("HandlerLeak")
    object : Handler(){
        @SuppressLint("NotifyDataSetChanged")
        override fun handleMessage(msg: Message) {
            Log.i(TAG, "handleMessage: ")
            when(msg.what){
                PULL_TO_FRESH -> {
                    if (fruits.size > 0){
                        fruits.removeAt(0) //删除第一条
                        adapter.notifyDataSetChanged()
                        swipeRefreshLayout.isRefreshing = false //false:刷新完成,true:刷新完成
                    }
                }
            }
        }
    }

    //初始化数据
    private fun initData() {
        Log.i(TAG, "initData: ")
        recyclerView = findViewById(R.id.recyclerView)
        swipeRefreshLayout = findViewById(R.id.swipRefreshLayout)

        fruits = ArrayList()
        FruitData.map.entries.forEach {
            val fruit = Fruit()
            fruit.name = it.key
            fruit.img = it.value

            fruits.add(fruit)
        }
        Log.i(TAG, "initData: fruits:$fruits")
    }

    /**
     * 加载菜单
     * @param menu Menu
     * @return Boolean
     */
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu, menu)
        return super.onCreateOptionsMenu(menu)
    }

    //菜单选择项
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when(item.itemId){
            //listView
            R.id.list_view_vertical -> showList(isVertical = true, isReverse = false)
            R.id.list_view_vertical_reverse -> showList(isVertical = true, isReverse = true)
            R.id.list_view_horizontal -> showList(false, isReverse = false)
            R.id.list_view_horizontal_reverse -> showList(false, isReverse = true)

            //GridView
            R.id.grid_view_vertical -> showGrid(isVertical = true, isReverse = false)
            R.id.grid_view_vertical_reverse -> showGrid(isVertical = true, isReverse = true)
            R.id.grid_view_horizontal -> showGrid(false, isReverse = false)
            R.id.grid_view_horizontal_reverse -> showGrid(false, isReverse = true)

            //StaggerView
            R.id.stagger_view_vertical -> showStagger(isVertical = true, isReverse = false)
            R.id.stagger_view_vertical_reverse -> showStagger(isVertical = true, isReverse = true)
            R.id.stagger_view_horizontal -> showStagger(false, isReverse = false)
            R.id.stagger_view_horizontal_reverse -> showStagger(false, isReverse = true)

            //moretype
            R.id.moretype -> showMoreType()
        }
        return super.onOptionsItemSelected(item)
    }

    private fun showMoreType() {
       //跳转到另外一个Activity中显示
        val intent = Intent(this,MoreTypeActivity::class.java)
        startActivity(intent)
    }

    private fun showList(isVertical:Boolean, isReverse:Boolean) {
        //是否是垂直布局
        val orientation = if(isVertical) RecyclerView.VERTICAL else RecyclerView.HORIZONTAL

        //设置布局管理器
        val linearLayoutManager = LinearLayoutManager(this)
        linearLayoutManager.orientation = orientation
        linearLayoutManager.reverseLayout = isReverse
        recyclerView.layoutManager = linearLayoutManager

        //获取adapter
        adapter = RecyclerViewAdapter(fruits)
        recyclerView.adapter = adapter
        setItemClick()

    }

    private fun setItemClick() {
        adapter.setRecyclerViewItemClick(object : BaseAdapter.RecyclerViewItemClickListener{
            override fun onItemClick(realPosition: Int) {
                Log.i(TAG, "onItemClick: position:${realPosition + 1}")
                updateLists(realPosition)
            }
        })
    }

    //简单的置顶操作,使点击的Item与ReclerView列表的第0个元素交换位置
    @SuppressLint("NotifyDataSetChanged")
    private fun updateLists(realPosition: Int) {
        Collections.swap(fruits, realPosition, 0)
        adapter.notifyDataSetChanged()
    }


    private fun showStagger(isVertical: Boolean, isReverse: Boolean) {
        //是否是出垂直布局
        val orientation = if (isVertical) StaggeredGridLayoutManager.VERTICAL else StaggeredGridLayoutManager.HORIZONTAL
        val staggeredGridLayoutManager = StaggeredGridLayoutManager(3,orientation)
        //是否反转
        staggeredGridLayoutManager.reverseLayout = isReverse
        //设置布局管理器
        recyclerView.layoutManager = staggeredGridLayoutManager

        //适配器
        adapter = StaggerViewAdapter(fruits)
        recyclerView.adapter = adapter
        setItemClick()


    }

    @SuppressLint("WrongConstant")
    private fun showGrid(isVertical: Boolean, isReverse: Boolean) {
        //是否是垂直布局
        val orientation = if (isVertical) GridLayoutManager.VERTICAL else GridLayoutManager.HORIZONTAL
        val gridLayoutManager = GridLayoutManager(this, 2)
        gridLayoutManager.reverseLayout = isReverse
        gridLayoutManager.orientation = orientation

        //设置布局管理器
        recyclerView.layoutManager = gridLayoutManager

        //适配器
        adapter = GridViewAdapter(fruits)
        recyclerView.adapter = adapter
        setItemClick()
    }

}

然后就是分别对应于ListView,GridView,瀑布流模型的代码了,这里由于有大量重复的代码,所以一抽取了一个Base类作为基类,使得代码更加简洁:

package com.example.a05_recyclerview.base

import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.a05_recyclerview.R
import com.example.a05_recyclerview.bean.Fruit

/**
 * @description: TODO
 * @author yueqingh
 * @date 2022/6/13 上午10:12
 * @version 1.0
 */
abstract class BaseAdapter(var datas: ArrayList<Fruit>) :
    RecyclerView.Adapter<BaseAdapter.MyViewHolder>() {

    private var mOnItemClickListener: OnItemClickListener ?= null

    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        var textView:TextView ?= null
        var imageView:ImageView ?= null
        init {
            textView = itemView.findViewById(R.id.title)
            imageView = itemView.findViewById(R.id.icon)
        }
        fun setData(fruit: Fruit) {
            textView?.text = fruit.fruitName
            imageView?.setImageResource(fruit.fruitImg)
        }

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val itemView:View = getSubView(parent, viewType)
        return MyViewHolder(itemView)
    }

    abstract fun getSubView(parent: ViewGroup, viewType: Int): View


    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        //获取位置信息
        holder.setData(datas[position])
        holder.itemView.setOnClickListener {
            mOnItemClickListener?.OnItemClick(position)
        }
    }

    override fun getItemCount(): Int {
        return datas.size
    }

    fun setOnItemClickListener(listener:OnItemClickListener) {
        //设置监听,其实就是要设置一个回调的接口
        this.mOnItemClickListener = listener
    }

    /**
     * 编写回调的步骤
     * 1。创建接口
     * 2. 定义接口内部的方法
     * 3. 外部设置接口(其实就是接口方法外部的实现)
     * 4. 接口方法的调用
     */
     interface OnItemClickListener{
        fun OnItemClick(position: Int)
    }

    companion object {
        private const val TAG = "BaseAdapter"
    }
}

然后各个适配器就分别继承自这个Base类就好了

ListViewAdapter:

package com.example.a05_recyclerview.adapter

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.a05_recyclerview.R
import com.example.a05_recyclerview.base.BaseAdapter
import com.example.a05_recyclerview.bean.Fruit

/**
 * @description: TODO
 * @author yueqingh
 * @date 2022/6/9 上午10:39
 * @version 1.0
 */
class RecyclerViewAdapter(datas: ArrayList<Fruit>) : BaseAdapter(datas) {

    @SuppressLint("InflateParams")
    override fun getSubView(parent: ViewGroup, viewType: Int): View {
        return LayoutInflater.from(parent.context).inflate(R.layout.recycler_view_item, null)
    }

}

GridViewAdapter:

package com.example.a05_recyclerview.adapter

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.a05_recyclerview.R
import com.example.a05_recyclerview.base.BaseAdapter
import com.example.a05_recyclerview.bean.Fruit

/**
 * @description: TODO
 * @author yueqingh
 * @date 2022/6/12 下午9:41
 * @version 1.0
 */
class GridViewAdapter(datas: ArrayList<Fruit>) : BaseAdapter(datas) {

    @SuppressLint("InflateParams")
    override fun getSubView(parent: ViewGroup, viewType: Int): View {
        return LayoutInflater.from(parent.context).inflate(R.layout.grid_view_item, null)
    }


}

瀑布流模型:StaggerViewAdapter:

package com.example.a05_recyclerview.adapter

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.a05_recyclerview.R
import com.example.a05_recyclerview.bean.Fruit


/**
 * @description: TODO
 * @author yueqingh
 * @date 2022/6/12 下午11:01
 * @version 1.0
 */
class StaggerViewAdapter(datas: ArrayList<Fruit>) :
    com.example.a05_recyclerview.base.BaseAdapter(datas) {

    @SuppressLint("InflateParams")
    override fun getSubView(parent: ViewGroup, viewType: Int): View {
        return LayoutInflater.from(parent.context).inflate(R.layout.stagger_view_item,null)
    }

}

多样式布局的化,设计到多种类型,所以这里选择从MainActivity跳转到另外的Activity进行显示,所以这里就有Activity之间的跳转的相关知识点

activity1:onCreate -> onStart -> onResume -> onPause

activity2: onCreate -> onStart -> onResume -> activity1 onStop

看MoreTypeActivity:

package com.example.a05_recyclerview

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.a05_recyclerview.adapter.MoreTypeAdapter
import com.example.a05_recyclerview.bean.MoreType
import com.example.a05_recyclerview.utils.FruitData
import java.util.*
import kotlin.collections.ArrayList

class MoreTypeActivity : AppCompatActivity() {

    private var datas:ArrayList<MoreType> ?= null
    private var recyclerView:RecyclerView ?= null
    private var adapter:MoreTypeAdapter ?= null


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

        showList()
        recyclerView?.addItemDecoration(DividerItemDecoration(this))
    }

    private fun showList() {
        Log.i(TAG, "showList: ")
        //设置布局管理器
        val layoutManager = LinearLayoutManager(this)
        recyclerView?.layoutManager = layoutManager

        //设置适配器
        adapter = datas?.let { MoreTypeAdapter(it) }
        Log.i(TAG, "showList: ${datas.toString()}")
        recyclerView?.adapter = this.adapter
    }

    private fun initData() {
        Log.i(TAG, "initData: ")
        recyclerView = findViewById(R.id.more_type)
        val random = Random()
        datas = ArrayList()
        FruitData.map.entries.forEach{
            val moreType = MoreType()
            moreType.icon = it.key
            moreType.title = it.value
            moreType.type = random.nextInt(3)
            Log.i(TAG, "initData: type: ${moreType.type}")
            datas?.add(moreType)
        }
        Log.i(TAG, "initData: ${datas.toString()}")
    }

    companion object {
        private const val TAG = "MoreTypeActivity"
    }
}

显示的实体类有以下两个:

1. MainActivity中的Fruit

package com.example.a05_recyclerview.bean

/**
 * @description: TODO
 * @author yueqingh
 * @date 2022/6/14 下午3:53
 * @version 1.0
 */
class Fruit{
    internal var fruitName:String ?= null
    internal var fruitImg:Int = 0
}

2. MoreTypeActivity中的MoreType

package com.example.a05_recyclerview.bean

/**
 * @description: TODO
 * @author yueqingh
 * @date 2022/6/15 下午2:55
 * @version 1.0
 */
class MoreType {
        internal var type:Int = 0
        internal var icon:Int = 0
        internal var title:String ?= null

        override fun toString(): String {
                return "MoreType(type=$type, icon=$icon, title=$title)"
        }


}

以及一个图片的集合工具类

package com.example.a05_recyclerview.utils

import com.example.a05_recyclerview.R
import com.example.a05_recyclerview.bean.Fruit

/**
 * @description: TODO
 * @author yueqingh
 * @date 2022/6/14 下午5:58
 * @version 1.0
 */
class FruitData {
    companion object{
        val map = hashMapOf<Int,String>(
            R.mipmap.pic01 to "哈密瓜",
            R.mipmap.pic02 to "梨",
            R.mipmap.pic03 to "榴莲",
            R.mipmap.pic04 to "樱桃",
            R.mipmap.pic05 to "橙子",
            R.mipmap.pic06 to "火龙果",
            R.mipmap.pic07 to "猕猴桃",
            R.mipmap.pic08 to "芒果",
            R.mipmap.pic09 to "苹果",
            R.mipmap.pic10 to "荔枝",
            R.mipmap.pic11 to "西瓜",
            R.mipmap.pic12 to "香蕉"
        )
    }

}


由于暂时还没有复习到Fragment所以暂时不使用fragment来进行多类型布局的展示,仅使用activity,这有助于记住活动的生命周期,以及活动之间跳转生命周期的变化

效果视频:

   不做展示,代码及全部代码,除了自定义分割线的代码未展示,其余代码亲测可用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值