Android 实例 - 分页器封装实现(上一页按钮、下一页按钮、当前页码 / 总页数、每页条数、总记录数)

发布于:2025-07-23 ⋅ 阅读:(24) ⋅ 点赞:(0)

一、需求

  • 分页器需要包含:【上一页按钮】、【下一页按钮】、【当前页码 / 总页数】、【每页条数】、【总记录数】
  1. 点击【上一页按钮】,渲染上一页的数据,如果当前页码为第一页,则禁用【上一页按钮】

  2. 点击【下一页按钮】,渲染下一页的数据,如果当前页码为最后一页,则禁用【下一页按钮】

  3. 点击【当前页码 / 总页数】,弹出对话框,可以选择页码,选择页码后,渲染该页码的数据


二、具体实现

1、Entity
  1. Student.java
package com.my.paging.model.entity;

public class Student {
    private int id;
    private String name;
    private int age;

    public Student() {
    }

    public Student(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  1. PageResult.java
package com.my.paging.model.entity;

import java.util.List;

public class PageResult<T> {
    private int pageNum;
    private int pageSize;
    private int pageTotal;
    private int total;
    private List<T> data;

    public PageResult() {
    }

    public PageResult(int pageNum, int pageSize, int pageTotal, int total, List<T> data) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.pageTotal = pageTotal;
        this.total = total;
        this.data = data;
    }

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getPageTotal() {
        return pageTotal;
    }

    public void setPageTotal(int pageTotal) {
        this.pageTotal = pageTotal;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }
}
2、Repository
  • StudentRepository.java
package com.my.paging.repository;

import com.my.paging.model.entity.PageResult;
import com.my.paging.model.entity.Student;

import java.util.ArrayList;
import java.util.List;

public class StudentRepository {
    private List<Student> students;

    private static final int TOTAL = 100;

    public StudentRepository() {
        students = new ArrayList<>();
        for (int i = 0; i < TOTAL; i++) {
            int id = i + 1;
            students.add(new Student(
                    id,
                    "test " + id,
                    20
            ));
        }
    }

    public PageResult<Student> getStudents(int pageNum, int pageSize) {
        int start = (pageNum - 1) * pageSize;
        int end = start + pageSize;
        if (end > TOTAL) {
            end = TOTAL;
        }
        List<Student> data = students.subList(start, end);

        PageResult<Student> pageResult = new PageResult<>();
        pageResult.setPageNum(pageNum);
        pageResult.setPageSize(pageSize);
        pageResult.setPageTotal((TOTAL + pageSize - 1) / pageSize);
        pageResult.setTotal(TOTAL);
        pageResult.setData(data);

        return pageResult;
    }
}
3、RecyclerView
(1)Layout
  • recycler_view_item_student.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/tv_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:textSize="18sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:textSize="16sp" />
</LinearLayout>
(2)Adapter
  • StudentRecyclerViewAdapter.java
package com.my.paging.adapter;

import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.my.paging.R;
import com.my.paging.model.entity.Student;

import java.util.List;

public class StudentRecyclerViewAdapter extends RecyclerView.Adapter<StudentRecyclerViewAdapter.StudentRecyclerViewViewHolder> {

    private List<Student> students;

    public StudentRecyclerViewAdapter() {
    }

    public void setStudents(List<Student> students) {
        this.students = students;
        notifyDataSetChanged();
    }

    @NonNull
    @Override
    public StudentRecyclerViewViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = View.inflate(parent.getContext(), R.layout.recycler_view_item_student, null);
        return new StudentRecyclerViewViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull StudentRecyclerViewViewHolder holder, int position) {
        holder.bind(students.get(position));
    }


    @Override
    public int getItemCount() {
        if (students == null) return 0;
        return students.size();
    }

    static class StudentRecyclerViewViewHolder extends RecyclerView.ViewHolder {

        private TextView tvId;
        private TextView tvName;
        private TextView tvAge;

        public StudentRecyclerViewViewHolder(@NonNull View itemView) {
            super(itemView);

            tvId = itemView.findViewById(R.id.tv_id);
            tvName = itemView.findViewById(R.id.tv_name);
            tvAge = itemView.findViewById(R.id.tv_age);
        }

        public void bind(Student student) {
            tvId.setText(String.valueOf(student.getId()));
            tvName.setText(student.getName());
            tvAge.setText(String.valueOf(student.getAge()));
        }
    }
}
4、PaginationView
(1)Layout
  • pagination_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="8dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_prev"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:enabled="false"
            android:text="上一页" />

        <LinearLayout
            android:id="@+id/ll_page_num_and_page_total"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="8dp">

            <TextView
                android:id="@+id/tv_page_num"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="1" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="/" />

            <TextView
                android:id="@+id/tv_page_total"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="1" />
        </LinearLayout>

        <Button
            android:id="@+id/btn_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:text="下一页" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal">

        <LinearLayout
            android:id="@+id/ll_page_size"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <TextView
                android:id="@+id/tv_page_size"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="10"
                android:textSize="12sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=" 条/页"
                android:textSize="12sp" />
        </LinearLayout>

        <LinearLayout
            android:id="@+id/ll_total"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""
                android:textSize="12sp" />

            <TextView
                android:id="@+id/tv_total"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="0"
                android:textSize="12sp" />

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text=""
                android:textSize="12sp" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>
(2)Observer
  • OnPageChangeObserver.java
package com.my.paging.customview.observer;

public interface OnPageChangeObserver {
    void onPageChange(int newPageNum);
}
(3)Code
  • PaginationView.java
package com.my.paging.customview;

import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.my.paging.R;
import com.my.paging.customview.observer.OnPageChangeObserver;

public class PaginationView extends LinearLayout {

    private Context context;

    private TextView tvPageNum;
    private TextView tvPageSize;
    private TextView tvPageTotal;
    private TextView tvTotal;
    private Button btnPrev;
    private Button btnNext;
    private LinearLayout llPageNumAndPageTotal;

    private int pageNum = 1;
    private int pageSize = 10;
    private int pageTotal = 0;
    private int total = 0;
    private String[] pageItems;

    private OnPageChangeObserver onPageChangeObserver;

    public PaginationView(Context context) {
        super(context);
        init(context);
    }

    public PaginationView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public PaginationView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    public PaginationView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    private void init(Context context) {
        this.context = context;

        LayoutInflater.from(context).inflate(R.layout.pagination_view, this, true);

        tvPageNum = findViewById(R.id.tv_page_num);
        tvPageSize = findViewById(R.id.tv_page_size);
        tvPageTotal = findViewById(R.id.tv_page_total);
        tvTotal = findViewById(R.id.tv_total);
        btnPrev = findViewById(R.id.btn_prev);
        btnNext = findViewById(R.id.btn_next);
        llPageNumAndPageTotal = findViewById(R.id.ll_page_num_and_page_total);

        btnPrev.setOnClickListener(v -> {
            pageNum--;
            tvPageNum.setText(String.valueOf(pageNum));
            if (onPageChangeObserver != null) {
                onPageChangeObserver.onPageChange(pageNum);
            }
        });

        btnNext.setOnClickListener(v -> {
            pageNum++;
            tvPageNum.setText(String.valueOf(pageNum));
            if (onPageChangeObserver != null) {
                onPageChangeObserver.onPageChange(pageNum);
            }
        });

        llPageNumAndPageTotal.setOnClickListener(view -> {
            pageItems = new String[pageTotal];
            for (int i = 0; i < pageTotal; i++) {
                pageItems[i] = "第 " + (i + 1) + " 页";
            }

            AlertDialog.Builder builder = new AlertDialog.Builder(context);

            builder.setTitle("选择页码");
            builder.setSingleChoiceItems(pageItems, -1, (dialog, which) -> {
                dialog.dismiss();

                pageNum = which + 1;
                tvPageNum.setText(String.valueOf(pageNum));
                if (onPageChangeObserver != null) {
                    onPageChangeObserver.onPageChange(pageNum);
                }
            });

            AlertDialog alertDialog = builder.create();

            alertDialog.show();
        });
    }

    public void setOnPageChangeObserver(OnPageChangeObserver onPageChangeObserver) {
        this.onPageChangeObserver = onPageChangeObserver;
    }

    public void render(int pageNum, int pageSize, int pageTotal, int total) {
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.pageTotal = pageTotal;
        this.total = total;

        tvPageNum.setText(String.valueOf(pageNum));
        tvPageSize.setText(String.valueOf(pageSize));
        tvPageTotal.setText(String.valueOf(pageTotal));
        tvTotal.setText(String.valueOf(total));

        btnPrev.setEnabled(pageNum > 1);
        btnNext.setEnabled(pageNum < pageTotal);
    }
}
5、Activity
(1)Layout
  • activity_pagination_view_test.xml
<?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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".PaginationViewTestActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_student"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <com.my.paging.customview.PaginationView
        android:id="@+id/pv_student"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
(2)Code
  • PaginationViewTestActivity.java
package com.my.paging;

import android.os.Bundle;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.my.paging.adapter.StudentRecyclerViewAdapter;
import com.my.paging.customview.PaginationView;
import com.my.paging.model.entity.PageResult;
import com.my.paging.model.entity.Student;
import com.my.paging.repository.StudentRepository;

import java.util.List;

public class PaginationViewTestActivity extends AppCompatActivity {

    private RecyclerView rvStudent;
    private PaginationView pvStudent;

    private int pageNum = 1;
    private int pageSize = 15;
    private int pageTotal = 0;
    private int total = 0;
    private List<Student> students;
    private StudentRepository studentRepository;
    private StudentRecyclerViewAdapter studentRecyclerViewAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_pagination_view_test);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        rvStudent = findViewById(R.id.rv_student);
        pvStudent = findViewById(R.id.pv_student);

        pvStudent.setOnPageChangeObserver(newPageNum -> {
            pageNum = newPageNum;
            doRequest();
            doRender();
        });

        studentRepository = new StudentRepository();

        studentRecyclerViewAdapter = new StudentRecyclerViewAdapter();
        rvStudent.setAdapter(studentRecyclerViewAdapter);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        rvStudent.setLayoutManager(linearLayoutManager);
        DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
        rvStudent.addItemDecoration(dividerItemDecoration);

        doRequest();
        doRender();
    }

    private void doRequest() {
        PageResult<Student> pageResult = studentRepository.getStudents(pageNum, pageSize);

        pageTotal = pageResult.getPageTotal();
        total = pageResult.getTotal();
        students = pageResult.getData();
    }

    private void doRender() {
        pvStudent.render(pageNum, pageSize, pageTotal, total);

        studentRecyclerViewAdapter.setStudents(students);
    }
}

网站公告

今日签到

点亮在社区的每一天
去签到