仿前端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="<<"
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=">>"
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>