android创建平板的分页页码

发布时间 2023-11-28 13:38:30作者: 乌拉小考

在横向平板显示分页页码的时候,要实现下面的效果

当默认分页超过5个之后中间显示 ... 然后两边的页码按钮点击之后移动页码,点击1、2页码不移动,点击了第3页之后,左边移动到 2、3、4页面,如下

使用RecyclerView列表实现,通过对Item的type进行分类来实现页码按钮和省略号,下面是分页列表的adapter类:


class PagesAdapter(var dataList: MutableList<Int>) :
    RecyclerView.Adapter<PagesHolder>() {

    // 页面按钮
    val TYPE_PAGE_BUTTON = 1
    // 页面省略号
    val TYPE_PAGE_DOT = 2
    // 页面不添加
    val TYPE_PAGE_NULL = 3

    // 最多按钮的数量
    val maxButtonNumber = 7
    val pageBtnCount = maxButtonNumber / 2
    // 左边的dot页面坐标
    var dotLeftPage: Int = pageBtnCount
    var dotRightPage: Int = dataList.size - (pageBtnCount+1)
    // 隐藏点点点
    var hideDotView: Boolean = false

    private var selectedPage: Int = 1
    private lateinit var itemClickListener: IPagesItemClickListener

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PagesHolder {
        if (viewType == TYPE_PAGE_BUTTON) {
            val rootView = LayoutInflater.from(parent.context)
                .inflate(R.layout.view_pages_button_item, parent, false)
            rootView.visibility = View.VISIBLE
            return PagesHolder(rootView)
        } else if (viewType == TYPE_PAGE_DOT) {
            val rootView = LayoutInflater.from(parent.context)
                .inflate(R.layout.view_pages_dot_item, parent, false)
            rootView.visibility = View.VISIBLE
            return PagesHolder(rootView)
        } else {
            val rootView = LayoutInflater.from(parent.context)
                .inflate(R.layout.view_pages_null_item, parent, false)
            rootView.visibility = View.GONE
            return PagesHolder(rootView)
        }
    }

    override fun onBindViewHolder(holder: PagesHolder, position: Int) {
        val type = getItemViewType(position)
        if (type == TYPE_PAGE_BUTTON) {
            val data = dataList[position]
            holder.tvPagesNum.text = "$data"
            holder.tvPagesNum.setOnClickListener {
                itemClickListener.onViewClick(data)
            }
            if (selectedPage == data) {
                // 当前选中页面
                holder.tvPagesNum.setTextColor(ColorUtils.getColor(R.color.white))
                holder.tvPagesNum.setBackgroundColor(ColorUtils.getColor(R.color.primary))
            } else {
                // 普通页面
                holder.tvPagesNum.setTextColor(ColorUtils.getColor(R.color.page_color_normal))
                holder.tvPagesNum.setBackgroundColor(ColorUtils.getColor(R.color.page_color_bg_normal))
            }
        } else if (type == TYPE_PAGE_DOT) {
            if (hideDotView) {
                holder.itemView.visibility = View.GONE
            } else {
                holder.itemView.visibility = View.VISIBLE
            }
        }
    }

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

    override fun getItemViewType(position: Int): Int {


        if (dataList.size > maxButtonNumber) {
            if (position < dotLeftPage) {
                // 小于坐标dotleftpage显示button,如果小于dotleftpage并且小于显示的按钮数量则隐藏
                if (position >= dotLeftPage - pageBtnCount) {
                    return TYPE_PAGE_BUTTON
                } else {
                    return TYPE_PAGE_NULL
                }
            }
            if (position == dotLeftPage) {
                if (dotLeftPage > dotRightPage) {
                    return TYPE_PAGE_BUTTON
                } else if(dotLeftPage == dotRightPage){
                    return TYPE_PAGE_DOT
                } else {
                    return TYPE_PAGE_DOT
                }
            }
            if (position > dotRightPage) {
                if (position < dotRightPage + pageBtnCount + 1) {
                    return TYPE_PAGE_BUTTON
                } else {
                    return TYPE_PAGE_NULL
                }
            }

            return TYPE_PAGE_NULL
        } else {
            // 小于maxButtonNumber则全部设置为普通的按钮
            return TYPE_PAGE_BUTTON
        }
    }

    fun setOnSignClickListener(listener: IPagesItemClickListener) {
        itemClickListener = listener
    }

    /**
     * 更新当前选中的页面,选中其他页面的时候
     * @param currentPage 指的是页码的值,从1开始
     */
    fun refreshPagesStatus(currentPage: Int) {
        // 将分页数字转换为rv的下标,从0开始的
        val realIndex = currentPage - 1
        // 如果更改的坐标在leftPage的后面第一和第二个
        if (realIndex < dotLeftPage) {
            if(realIndex == (dotLeftPage - 1)) {
                if (dotLeftPage > dotRightPage) {
                    // 不移动了
                } else {
                    // 向右移动一位
                    dotLeftPage += 1
                }
            } else if (realIndex == (dotLeftPage - (pageBtnCount))){
                // 向左移动一位
                dotLeftPage -= 1
            }
        } else {
            // 不改变位置
        }
        if (dotLeftPage<pageBtnCount) {
            dotLeftPage = pageBtnCount
        }

        // 如果在rightpage的右边,则右移一位
        if (realIndex > dotRightPage) {
            if (realIndex == dotRightPage + 1) {
                if (dotRightPage < dotLeftPage) {
                    // 不移动了
                } else {
                    // 左边移动一位
                    dotRightPage -= 1
                }
            } else if (realIndex == dotRightPage + pageBtnCount) {
                if (realIndex == dataList.size - 1) {
                    // 最后一页面了
                } else {
                    // 向右边移动一位
                    dotRightPage += 1
                }
            } else {
                // 中间不动
            }
        }
        if (dotRightPage > dataList.size - pageBtnCount) {
            dotRightPage = dataList.size - pageBtnCount
        }

        hideDotView = dotLeftPage > dotRightPage

        selectedPage = currentPage
        notifyDataSetChanged()
    }

    // 初始化的时候,页面默认选中1,刷新adapter
    fun refresh() {
        // 根据数量修改
        dotLeftPage = pageBtnCount
        dotRightPage = dataList.size - (pageBtnCount + 1)
        hideDotView = dotLeftPage > dotRightPage
        selectedPage = 1
        notifyDataSetChanged()
    }

}

class PagesHolder(view: View) : RecyclerView.ViewHolder(view) {
    val tvPagesNum = view.findViewById<TextView>(R.id.tv_pages_num)
}

分页adapter的使用跟普通的recyclerview使用一样,只需要将分页的列表传入:

rv_pages.layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
// 将页码传入到分页的dataList里面
        for (i in 1..5) {
            pagesList.add(i)
        }
        pagesAdapter = PagesAdapter(pagesList)
        pagesAdapter.setOnSignClickListener(object : IPagesItemClickListener {
            override fun onViewClick(itemData: Int) {
                currentPage = itemData
                changePatientPage(currentPage)
            }

        })
        rv_pages.adapter = pagesAdapter