Bootstrap

Android仿前端分页组件pagination

仿前端pagination

Android仿前端分页组件pagination

最近Android原生有个需求就是做个分页组件,不用上拉加载,因为数据量太大用户喜欢前端的方式,UI主要是拼凑比较简单,主要补充了一些判断越界和数据不全的细节,记录方便以后COPY

适配器用的万能的

maven { url 'https://jitpack.io' }
  implementation "io.github.cymchad:BaseRecyclerViewAdapterHelper4:4.1.4"

使用示例

 

   
   //设置监听即可
 pageBottomView.mOnPageNumChangeListener = object : PageBottomView.OnPageChangeListener {
                override fun onPageChange(page: Int, mustRefresh: Boolean) {
                    if (mustRefresh) {
                        mViewModel.goodsPage = page
                        val name = etGoodsName.text.trim().toString()
                        mViewModel.filterList(name)
                    }
                }

            }  




fun getGoodsList(goodsName: String? = null) {
        ApiClient.mainService().getGoodsList(
            page = goodsPage,
            page_size = goodsSize,
            fuzzySearch = goodsName,
            goodsCategoryId = selectDishType.goodsCategoryId
        )
            .enqueue(object : BaseCallBack<GoodsPage>() {
                override fun success(response: HttpResult<GoodsPage>) {
                    LogUtils.logD(TAG, "getGoodsTypeList:${response.data?.data?.size}")
                    response.data?.run {
//                        if (current_page?.toInt() == 1) {
//
//                        }
                        // 设置最大值 接口没有则可以不显示 或者用固定值
                        binding.pageBottomView.setPageSize(last_page, total)
                        // 因为是前端单页分页 所以都得清除
                        // 主页面列表更换
                        goodsList.clear()
                        data?.run {
                            goodsList.addAll(this)
                        }
                        goodsLiveData.postValue(goodsList)

                       
                    }
                }

            })

    }

PageBottomView 

package your pkg

import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder
import your R 

class PageBottomView : LinearLayout {


    var pageIndex = 1
    var pageMax = 10
    var pageMin = 3
    var pageMore = arrayListOf(3, 4, 5, 6, 7)


    constructor(context: Context) : super(context) {
        initView(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        initView(context)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        initView(context)
    }

    constructor(
        context: Context,
        attrs: AttributeSet?,
        defStyleAttr: Int,
        defStyleRes: Int
    ) : super(context, attrs, defStyleAttr, defStyleRes) {
        initView(context)
    }

//    var weightValue = 0.00f
//    var mEditText: EditText? = null

    class PageAdapter : BaseQuickAdapter<Int, QuickViewHolder>() {
        var mPage = 0
        override fun onCreateViewHolder(
            context: Context,
            parent: ViewGroup,
            viewType: Int
        ): QuickViewHolder {
            return QuickViewHolder(R.layout.item_rv_page, parent)
        }


        override fun onBindViewHolder(
            holder: QuickViewHolder,
            position: Int,
            item: Int?
        ) {
            item?.run {
                holder.setText(R.id.tvPage, "${item}")
                selectPage(holder.getView(R.id.tvPage), mPage == item)
            }
        }

        fun updatePageUI(page: Int) {
            mPage = page
            notifyDataSetChanged()
        }

        fun selectPage(textView: TextView, isSelect: Boolean) {
            if (isSelect) {
                textView.setBackgroundResource(R.drawable.shape_rect_bg_f2_blue_4)
                textView.setTextColor(Color.WHITE)
            } else {
                textView.setBackgroundResource(R.drawable.shape_rect_dialog_bg_line_4)
                textView.setTextColor(Color.parseColor("#FF333333"))
            }
        }

    }

    private val mPageAdapter = PageAdapter()

    var mOnPageNumChangeListener: OnPageChangeListener? = null

    var rvPage: RecyclerView? = null
    var tvMore: TextView? = null
    var tvPageLeftIndex: TextView? = null
    var tvPageRightIndex: TextView? = null
    var tvPageStart: TextView? = null
    var tvPageStart2: TextView? = null
    var tvPageEnd: TextView? = null
    var ivPageRuduce: ImageView? = null
    var ivPageAdd: ImageView? = null
    var tvGoPageEdit: TextView? = null
    var etPageNum: EditText? = null
    var tvTotal: TextView? = null
    private fun initView(context: Context) {
        inflate(context, R.layout.view_page_index, this)

        rvPage = findViewById(R.id.rvPage)
        tvMore = findViewById(R.id.tvMore)
        tvPageLeftIndex = findViewById(R.id.tvPageLeftIndex)
        tvPageRightIndex = findViewById(R.id.tvPageRightIndex)
        tvPageStart = findViewById(R.id.tvPageStart)
        tvPageStart2 = findViewById(R.id.tvPageStart2)
        tvPageEnd = findViewById(R.id.tvPageEnd)
        ivPageRuduce = findViewById(R.id.ivPageRuduce)
        ivPageAdd = findViewById(R.id.ivPageAdd)
        tvGoPageEdit = findViewById(R.id.tvGoPageEdit)
        etPageNum = findViewById(R.id.etPageNum)
        tvTotal = findViewById(R.id.tvTotal)

        rvPage?.adapter = mPageAdapter
        rvPage?.setLayoutManager(
            LinearLayoutManager(
                context,
                LinearLayoutManager.HORIZONTAL, false
            )
        )

        tvMore?.setOnClickListener {
            if (rvPage?.visibility == View.GONE) {
                rvPage?.visibility = View.VISIBLE
                tvPageLeftIndex?.visibility = View.VISIBLE
                tvPageRightIndex?.visibility = View.VISIBLE
            } else {
                rvPage?.visibility = View.GONE
                tvPageLeftIndex?.visibility = View.GONE
                tvPageRightIndex?.visibility = View.GONE

            }
        }

        tvPageStart?.setOnClickListener {
            onPageChange(1, true)
        }

        tvPageStart2?.setOnClickListener {
            onPageChange(2, true)

        }

        tvPageStart?.setOnClickListener {
            onPageChange(1, true)

        }

        tvPageEnd?.setOnClickListener {
            onPageChange(pageMax, true)
        }

        ivPageRuduce?.setOnClickListener {
            reducePageOne()
        }

        ivPageAdd?.setOnClickListener {
            addPageOne()
        }



        tvPageLeftIndex?.setOnClickListener {
            reducePageNext()
            initData()
        }
        tvPageRightIndex?.setOnClickListener {
            addPageNext()
            initData()
        }

        mPageAdapter.setOnItemClickListener { adapter, view, position ->
            pageIndex = adapter.items[position]
            onPageChange(pageIndex, true)
        }

        tvGoPageEdit?.setOnClickListener {
            pageIndex = (etPageNum?.text?.trim() ?: "0").toString().toInt()
            if (pageIndex > pageMax) {
                pageIndex = pageMax
            }

            if (pageIndex < pageMin) {
                pageIndex = pageMin
            }

            etPageNum?.setText(pageIndex.toString())
            etPageNum?.clearFocus()
            pageMore.clear()

            var right = pageIndex + 4

            if (pageIndex + 4 > pageMax - 1) {
                right = pageMax - 1
            }

            if (right < 7) {
                right = 7
            }

            for (i in right - 4..right) {
                pageMore.add(i)
            }
            onPageChange(pageIndex, true)
        }

        // 初始化UI
        onPageChange(1, false)
    }

    fun setTotalText(des: String) {
        tvTotal?.text = des
    }

    private fun initData() {
        // fixme  5 为一段  不包含 1 2 10 逻辑待补充
        mPageAdapter.submitList(pageMore)
        onPageChange(pageIndex, true)
    }

    fun initDataFirst() {
        pageIndex = 1
        pageMore = arrayListOf(3, 4, 5, 6, 7)
        // fixme  5 为一段  不包含 1 2 10 逻辑待补充
        mPageAdapter.submitList(pageMore)
        onPageChange(pageIndex, true)
    }


    private fun reducePageOne() {
        pageIndex = if (pageIndex - 1 >= 1) {
            --pageIndex
        } else {
            1
        }
        if (pageIndex < pageMore[0] && pageMore[0] - 1 > 2) {
            // pageMore 每个数加1
            for (i in 0..4) {
                pageMore[i] = pageMore[i] - 1
            }
        }
        onPageChange(pageIndex, true)
    }

    private fun addPageNext() {
        if (pageMore[4] + 5 < pageMax) {
            for (i in 0..4) {
                pageMore[i] = pageMore[i] + 5
            }
        } else {
            for (i in 0..4) {
                pageMore[i] = (pageMax - 5) + i
            }
        }
        pageIndex = pageMore[2]
        onPageChange(pageIndex, true)

    }

    private fun reducePageNext() {
        if (pageMore[0] - 5 > 2) {
            for (i in 0..4) {
                pageMore[i] = pageMore[i] - 5
            }
        } else {
            for (i in 0..4) {
                pageMore[i] = i + pageMin
            }
        }

        pageIndex = pageMore[2]
        onPageChange(pageIndex, true)
    }

    private fun addPageOne() {
        pageIndex = if (pageIndex + 1 <= pageMax) {
            ++pageIndex
        } else {
            pageMax
        }
        if (pageIndex > pageMore[4] && pageMore[4] + 1 < pageMax) {
            // pageMore 每个数加1
            for (i in 0..4) {
                pageMore[i] = pageMore[i] + 1
            }
        }
        onPageChange(pageIndex, true)
    }


    private fun onPageChange(page: Int, mustRefresh: Boolean) {
        pageIndex = page
        if (pageIndex in 3..<pageMax) {
            rvPage?.visibility = View.VISIBLE
            tvPageLeftIndex?.visibility = View.VISIBLE
            tvPageRightIndex?.visibility = View.VISIBLE
            mPageAdapter.submitList(pageMore)
        }

        selectPage(tvPageStart, pageIndex == 1)
        selectPage(tvPageStart2, pageIndex == 2)
        selectPage(tvPageEnd, pageIndex == pageMax)
        mPageAdapter.updatePageUI(pageIndex)

        mOnPageNumChangeListener?.onPageChange(pageIndex, mustRefresh)
    }

    private fun selectPage(textView: TextView?, isSelect: Boolean) {
        textView?.run {
            if (isSelect) {
                setBackgroundResource(R.drawable.shape_rect_bg_f2_blue_4)
                setTextColor(Color.WHITE)
            } else {
                setBackgroundResource(R.drawable.shape_rect_dialog_bg_line_4)
                setTextColor(Color.parseColor("#FF333333"))
            }
        }
    }

    fun setPageSize(maxPage: Int, maxSize: Int) {
        pageMax = maxPage
        if (pageMax < 10) {
            pageMax = 10
        }
        // 操作max
        tvPageEnd?.text = pageMax.toString()
        // 实际max
        setTotalText("共${maxPage}页 ${maxSize}条")
    }


    interface OnPageChangeListener {
        fun onPageChange(page: Int, mustRefresh: Boolean)
    }
}

view_page_index

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical|end"
    android:orientation="horizontal"
    android:paddingHorizontal="@dimen/dp_90"
    android:paddingVertical="@dimen/dp_20">

    <TextView
        android:id="@+id/tvTotal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_16"
        tools:text="共10页,100条数据" />

    <ImageView
        android:id="@+id/ivPageRuduce"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_10"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:padding="@dimen/dp_5"
        android:src="@mipmap/icon_page_left" />


    <TextView
        android:id="@+id/tvPageStart"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_12"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:text="1"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <TextView
        android:id="@+id/tvPageStart2"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_6"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:text="2"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />


    <TextView
        android:id="@+id/tvPageLeftIndex"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_6"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:text="&lt;&lt;"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvPage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="@dimen/dp_6"
        tools:listitem="@layout/item_rv_page" />

    <TextView
        android:id="@+id/tvPageRightIndex"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_6"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:text="&gt;&gt;"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <TextView
        android:id="@+id/tvMore"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_6"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:text="···"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <TextView
        android:id="@+id/tvPageEnd"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_6"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:text="10"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <ImageView
        android:id="@+id/ivPageAdd"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_12"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:padding="5dp"
        android:src="@mipmap/icon_page_right" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/dp_6"
        android:gravity="center"
        android:text="28条/页"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/dp_6"
        android:gravity="center"
        android:text="跳至"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <EditText
        android:id="@+id/etPageNum"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_6"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:inputType="number"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/dp_6"
        android:gravity="center"
        android:text="页"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

    <TextView
        android:id="@+id/tvGoPageEdit"
        android:layout_width="wrap_content"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_12"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:paddingHorizontal="@dimen/dp_20"
        android:text="跳转"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />
</LinearLayout>

item_rv_page
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tvPage"
        android:layout_width="@dimen/dp_28"
        android:layout_height="@dimen/dp_28"
        android:layout_marginStart="@dimen/dp_4"
        android:background="@drawable/shape_rect_dialog_bg_line_4"
        android:gravity="center"
        android:text="10"
        android:textColor="#FF333333"
        android:textSize="@dimen/dp_18" />

</FrameLayout>

R.drawable.shape_rect_bg_f2_blue_4
<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#FF2A82E4" />
    <corners
        android:radius="4dp" />
</shape>

R.drawable.shape_rect_dialog_bg_line_4
<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="@android:color/white" />
    <corners
        android:radius="4dp" />
    <stroke
        android:width="0.5dp"
        android:color="#FFB0B0B0" />
</shape>

;