Paginación de paginación personalizada

No digas tonterías sobre el código

package com.mgo.basemodule.common.manager.paging;

import android.annotation.SuppressLint;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import com.mgo.logimpl.MyLog;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import io.reactivex.Flowable;
import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

/**
 * @package com.mgo.mainmodule.viewmodel2
 * @user by lvyaodong
 * @date 2020/8/27
 * @email [email protected]
 */
public class Paging<T extends PagingDataBase, D> {

    private static final String TAG = "Paging";
    private Scheduler mLoopScheduler;
    //发射数据
    private MutableLiveData<List<D>> postValue = new MutableLiveData<>();
    //数据转换
    private Converter<T, D> converter;
    //页面切换监听
    private OnPageChangerListener mOnPageChangerListener;

    //每页多少个数据
    private int SIZE = -1;


    //数据
    private List<T> mData;
    //总共有几页
    private int mPageCount = 0;
    //当前位于第几页
    private int mCurPage = 0;
    //总的数据大小
    private int mDataSize = 0;

    //多长时间发射一次数据 这个先不实现 先交给外部
    private long mChangeTime = 10 * 1000;

    private Disposable mSubscribe;

    private Paging() {
        mLoopScheduler = Schedulers.from(Executors.newFixedThreadPool(2));
    }

    public Paging(Converter<T, D> converter, int SIZE) {
        this();
        this.converter = converter;
        this.SIZE = SIZE;
    }

    public int getPageCount() {
        return mPageCount;
    }

    public int getCurPage() {
        return mCurPage;
    }

    public void setChangeTime(long mChangeTime) {
        this.mChangeTime = mChangeTime;
    }

    public void setSize(int size) {
        this.SIZE = size;
    }

    public void setConverter(Converter<T, D> converter) {
        this.converter = converter;
    }

    public void setOnPageChangerListener(OnPageChangerListener mOnPageChangerListener) {
        this.mOnPageChangerListener = mOnPageChangerListener;
    }

    public void setDataSource(List<T> data) {
        if (SIZE <= 0) {
            MyLog.d(TAG, "You should set SIZE first");
            return;
        }

        if (converter == null) {
            MyLog.d(TAG, "You should set data converter first");
            return;
        }

        this.mData = data;
        this.mCurPage = 0;
        this.mDataSize = 0;
        this.mPageCount = 0;
        loadData(data);
    }

    public LiveData<List<D>> getPostValue() {
        return postValue;
    }

    /**
     * 可循环下一页
     *
     * @return 返回是否为最后一页
     */
    public boolean nextPageWithLoop() {
        if (nextPage()) {
            MyLog.d(TAG, "Start from first page!");
            firstPage();
            return true;
        }
        return false;
    }

    /**
     * 不可循环下一页
     *
     * @return
     */
    public boolean nextPage() {
        MyLog.d(TAG, "Try execute next page.");

        if (mPageCount == 0) {
            MyLog.d(TAG, "No data,no page!");
            return true;
        }

        if (mCurPage >= mPageCount - 1) {
            MyLog.d(TAG, "It's already the last page.");
            return true;
        }
        int start = (++mCurPage) * SIZE;
        int end = Math.min((mCurPage + 1) * SIZE, mDataSize);

        MyLog.d(TAG, "Execute next page success. start: " + start + "--> end: " + end + ", curPage: " + mCurPage);
        postPageChange(start, end);

        if (mOnPageChangerListener != null) {
            mOnPageChangerListener.onPageChange(mCurPage);
        }
        return false;
    }

    /**
     * 上一页
     */
    public void prePage() {
        MyLog.d(TAG, "Try execute pre page.");
        if (mPageCount == 0) {
            MyLog.d(TAG, "No data,no page!");
            return;
        }
        if (mCurPage <= 0) {
            MyLog.d(TAG, "It's already the first page.");
            return;
        }

        int end = Math.min(mCurPage * SIZE, mDataSize);
        int start = (--mCurPage) * SIZE;

        MyLog.d(TAG, "Execute pre page success. start: " + start + "--> end: " + end + ", curPage: " + mCurPage);
        postPageChange(start, end);
        if (mOnPageChangerListener != null) {
            mOnPageChangerListener.onPageChange(mCurPage);
        }
    }

    @SuppressLint("DefaultLocale")
    public void skipToSomePage(int page) {
        MyLog.d(TAG, String.format("Try skip to '%d' page.", page));
        if (mPageCount == 0) {
            MyLog.d(TAG, "No data,no page!");
            return;
        }

        if (page > mPageCount - 1 || page < 0) {
            MyLog.d(TAG, String.format("No '%d' page! Please re-skip! Page should be 0<=page<=mPageCount - 1", page));
            return;
        }

        mCurPage = page;

        int start = mCurPage * SIZE;
        int end = (++mCurPage) * SIZE;
        end = Math.min(end, mDataSize);
        MyLog.d(TAG, "Execute next page success. start: " + start + "--> end: " + end + ", curPage: " + mCurPage);
        postPageChange(start, end);

        if (mOnPageChangerListener != null) {
            mOnPageChangerListener.onPageChange(mCurPage);
        }
    }


    public void startLoop() {
        if (mChangeTime <= 0) {
            MyLog.d("Please set time first!");
            return;
        }
        cancelLoop();
        mSubscribe = Flowable.interval(mChangeTime, mChangeTime, TimeUnit.MILLISECONDS)
                .subscribeOn(mLoopScheduler)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> nextPageWithLoop());
    }

    public void cancelLoop() {
        dispose(mSubscribe);
    }


    private void loadData(List<T> data) {
        if (data == null || data.size() <= 0) {
            MyLog.d(TAG, "no data source!");
            return;
        }

        //计算数据量
        mDataSize = data.size();
        //页数
        int page = mDataSize / SIZE;
        MyLog.d(TAG, "page:" + page);
        if (mDataSize % SIZE == 0) {
            this.mPageCount = page;
        } else {
            this.mPageCount = page + 1;
        }
        MyLog.d(TAG, "PageCount:" + mPageCount);
        //为每个数据添加具体数据位置
        for (int i = 0; i < mDataSize; i++) {
            data.get(i).setPagItemIndex(i);
        }

        if (mOnPageChangerListener != null) {
            mOnPageChangerListener.pagingInitDone(mPageCount);
        }

        //发射第一页数据
        firstPage();
    }

    private void firstPage() {
        if (mPageCount == 0) {
            MyLog.d(TAG, "FirstPage PageCount:" + mPageCount);
            return;
        }

        if (converter == null) {
            MyLog.d(TAG, "You should set data converter first");
            return;
        }
        MyLog.d(TAG, "Post first page datas!");
        mCurPage = 0;
        postValue.postValue(converter.convertData(mData.subList(0, Math.min(mDataSize, SIZE))));
        if (mOnPageChangerListener != null) {
            mOnPageChangerListener.onPageChange(mCurPage);
        }
    }

    private void postPageChange(int pageNum, int size) {
        if (converter == null) {
            MyLog.d(TAG, "You should set data converter first");
            return;
        }
        postValue.postValue(converter.convertData(mData.subList(pageNum, size)));
    }

    public interface Converter<T, D> {
        List<D> convertData(List<T> data);
    }

    public interface OnPageChangerListener {
        void onPageChange(int curPage);

        void pagingInitDone(int pageCount);
    }

    private void dispose(Disposable disposable) {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }

}



public class PagingDataBase implements Serializable {

    private int pagItemIndex;

    public int getPagItemIndex() {
        return pagItemIndex;
    }

    public void setPagItemIndex(int pagItemIndex) {
        this.pagItemIndex = pagItemIndex;
    }
}

De hecho, es importar la fuente de datos, procesar los datos usted mismo y luego transmitirlos con la ayuda de LiveData. Internamente, RxJava se utiliza para realizar el procesamiento automático de cambio de página, sería mejor si se pudiera realizar un ciclo de vida para realizar la destrucción automática y el cambio de página automático.

Considere la optimización de publicaciones:

  • Aumente el ciclo de vida, la destrucción automática y el carrusel automático
  • Eliminar la gran dependencia de RxJava
  • Mejorar el método de cambio de página
    Uso:

1. Inicialización

//两个泛型第一个是传入的数据,第二个是你要转成的数据,这个地方主要是为了能够直接拿到想要的数据,实现Converter数据转换的方法
//第二个参数是要分页的个数 也就是4个一页
Paging<T,D> mPaging = new Paging<>((Paging.Converter<T, D>) data -> data, 4);

2. Datos de configuración

//设置数据后自动发射第一页数据 如果不符合你的需求可以自己去修改源码
mPaging.setDataSource(data);

3. Datos de la página siguiente y de la página anterior

//下一页数据
mPaging.nextPage()
//上一页数据
mPaging.prePage()

4. Datos de la página siguiente, ciclo automático (si la página actual es la última página y la página siguiente no tiene datos, los datos de la primera página se transmitirán desde el principio)

//下一页数据
mPaging.nextPageWithLoop()

5. Ir a una página

//这个添加后未测试过
mPaging.skipToSomePage(int page)

6. Supervisión de datos

mPaging.getPostValue().observe(this, entWxAppBeans -> {
            //收到数据
        });

7. Inicialización de página, monitoreo de cambio de página

mPaging.setOnPageChangerListener(new Paging.OnPageChangerListener() {
            @Override
            public void onPageChange(int curPage) {
                MyLog.d(TAG, String.format("Page change to %s.", curPage));
              //翻页监听
            }

            @Override
            public void pagingInitDone(int pageCount) {
               //数据加载完成,页面总数回调
            }
        });

Supongo que te gusta

Origin blog.csdn.net/u011148116/article/details/108666892
Recomendado
Clasificación