符合mvp模式的可上拉刷新recyclerview

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.yds.tingli.R;

public class AppMainCardView extends RelativeLayout {
    TextView nameView;

    public AppMainCardView(Context context) {
        this(context,null);
    }

    public AppMainCardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        View view = LayoutInflater.from(context).inflate(R.layout.mainitem, this, true);
        nameView = view.findViewById(R.id.title);
    }

    public void setName(String name) {
        nameView.setText(name);
    }
}
public class Constance {
    public static final int ITEM_IN_A_PAGE = 20;
}
import com.yds.tingli.ElyBean;

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

public class PartBean {
    public String title;//2020年12月英语四级听力真题 短文(1)
    public List<ElyBean> elyBeanList = new ArrayList<>();
    public String getName(){
        return title;
    }
}
import android.content.Context;
import android.util.Log;
import android.view.View;

import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

public class PullUpRecyclerController {
    private RecyclerView mRecyclerView;
    private RecyclerAdapter mAdapter;
    private int mLastVisibleItemPosition = 0;
    private LinearLayoutManager mLayoutManager;

    private Context mContext;

    private OnNeedLoadListener mOnNeedLoadListener;

    public PullUpRecyclerController(Context context, RecyclerView recyclerView) {
        onCreate(context, recyclerView);
    }

    protected void onCreate(Context context, RecyclerView recyclerView) {
        mContext = context;

        mRecyclerView = recyclerView;
        mLayoutManager = new LinearLayoutManager(context);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    }

    public View getRecyclerView() {
        return mRecyclerView;
    }

    /**
     * 构造方法已经调用此方法 当想要更换listener时再调用此方法
     *
     * @param listener
     */
    public void setOnNeedLoadListener(OnNeedLoadListener listener) {
        this.mOnNeedLoadListener = listener;
    }

    public interface OnNeedLoadListener {
        public void loadMore(int from, int length);
    }

    /**
     * 第一次显示recyclerView的时候调用的方法。
     *
     * @param list
     */
    @SuppressWarnings("deprecation")
    public void showFirstpageItems(List<PartBean> list) {
        mAdapter = new RecyclerAdapter(mContext, list);
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView,
                                             int newState) {

                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE
//                        && mLastVisibleItemPosition + 1 >= mAdapter
                        && mLastVisibleItemPosition + 1 == mAdapter
                        .getItemCount()) {
                    if (mOnNeedLoadListener != null) {
                        /**
                         * 在调用回调接口前,要先确定是否已经在回调了 没有在回调的话,还要更新footer
                         */
                        if (RecyclerModule.isLoadingMore) {
                            Log.e("aaaaa", "RecyclerModule.isLoadingMore");
                            return;
                        }
                        RecyclerModule.isLoadingMore = true;
                        setLoadStatusNrefreshFooter(RecyclerAdapter.LoadStatus.LOADING_MORE);

                        /**
                         * 调用回调接口
                         */
                        mOnNeedLoadListener.loadMore(mAdapter.getItemCount() - 1,
                                Constance.ITEM_IN_A_PAGE);
                    }

                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

                super.onScrolled(recyclerView, dx, dy);
                mLastVisibleItemPosition = mLayoutManager
                        .findLastVisibleItemPosition();
            }
        });

    }

    /**
     * 显示更多条目 应该先调用showFirstpageItems方法
     *
     * @param list
     */
    public void showMoreItems(List<PartBean> list) {
        mAdapter.addAllNRefresh(list);
    }

    /**
     * 调用adapter的同名方法 并暴露给ViewLayer
     *
     * @param clickLoadMore
     */
    public void setLoadStatusNrefreshFooter(RecyclerAdapter.LoadStatus clickLoadMore) {
        mAdapter.setLoadStatusNrefreshFooter(clickLoadMore);
    }

    /**
     * 要再showFirstPageItems之后调用此方法
     *
     * @param listener
     */
    public void setOnItemClickListener(Presenter.RecyclerViewOnClickListener listener) {
        mAdapter.setOnItemClickListener(listener);
    }
}
import java.util.ArrayList;
import java.util.List;

public class RecyclerModule {

    public static boolean isLoadingMore = false;
    Thread thread;
    boolean shouldStop = false;

    public void loadMore(int from, int length, Presenter.OnDataLoadedListener listener) {
        isLoadingMore = true;

        if(from > 30){
            thread = new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    isLoadingMore = false;
                    if(shouldStop){
                        return;
                    }
                    listener.onDataLoadFailed(new Throwable("asdf"));
                }
            };

            thread.start();

            return;
        }else{
            thread = new Thread() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    List<PartBean> beanList = new ArrayList<>();
                    for (int i = 0; i < length; i++) {
                        PartBean partBean0 = new PartBean();
                        partBean0.title = "asdf" + (from + i);
                        beanList.add(partBean0);
                    }
                    isLoadingMore = false;
                    if(shouldStop){
                        return;
                    }
                    listener.onDataLoaded(beanList);
                }
            };

            thread.start();
        }


    }

    public void cancelAll(){
        shouldStop = true;
        if(thread != null){
            thread.interrupt();
        }
    }

}

 

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import com.yds.tingli.R;

import java.util.List;

public class ViewLayer {
    private PullUpRecyclerController mRecyclerController;
    private View mView;
    private TextView mErrorTextView;
    private ProgressBar mProgressBar;
    Context context;

    public ViewLayer(Context context) {
        this.context = context;

        LayoutInflater inflater = LayoutInflater.from(context);
        mView = inflater.inflate(R.layout.fraglayout, null);

        RecyclerView recyclerView = (RecyclerView) mView
                .findViewById(R.id.recyclerView);
        mRecyclerController = new PullUpRecyclerController(context,
                recyclerView);

        mErrorTextView = (TextView) mView.findViewById(R.id.errorView);
        mProgressBar = (ProgressBar) mView.findViewById(R.id.loadingView);


    }

    /**
     * 第一次showContent之前一定要先调用这个方法
     *
     * @param mOnNeedLoadListener
     */
    public void setOnNeedLoadListener(PullUpRecyclerController.OnNeedLoadListener mOnNeedLoadListener) {
        mRecyclerController.setOnNeedLoadListener(mOnNeedLoadListener);
    }


    public View getInnerView() {
        return mView;
    }

    public void showLoading() {
        mErrorTextView.setVisibility(View.INVISIBLE);
        mProgressBar.setVisibility(View.VISIBLE);
    }

    /**
     * 在显示第一页的时候调用,之后就没再调用了
     *
     * @param beanList
     * @param onclickListener
     */
    public void showFirstPageContent(List<PartBean> beanList,
                                     Presenter.RecyclerViewOnClickListener onclickListener) {
//        mErrorTextView.setVisibility(View.INVISIBLE);
        Log.e("aaaaaaaaaa", "showFirstPageContent: 不可见" );
        mProgressBar.setVisibility(View.INVISIBLE);

        mRecyclerController.showFirstpageItems(beanList);
        mRecyclerController.setOnItemClickListener(onclickListener);
    }

    public void showError(Throwable e) {
        Log.e("aaaaaaaaaa", "showFirstPageContent: 不可见2" );

        mProgressBar.setVisibility(View.INVISIBLE);
        mErrorTextView.setVisibility(View.VISIBLE);
    }

    public void showMoreContent(List<PartBean> cardViewBeanList) {
        mRecyclerController.showMoreItems(cardViewBeanList);
    }

    public void setLoadStatusNrefreshFooter(RecyclerAdapter.LoadStatus clickLoadMore) {
        mRecyclerController.setLoadStatusNrefreshFooter(clickLoadMore);
    }

    /**
     * 加载更多未获取到数据时调用此方法
     */
    public void showLoadMoreFailure() {
    }
}
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

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

import com.yds.tingli.R;

import java.util.List;

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private static final int VIEW_TYPE_FOOTER = 0;
    private static final int VIEW_TYPE_ITEM = 1;
    private List<PartBean> mList;
    private LayoutInflater mInflater;
    private Context mContext;
    private LoadStatus mLoadStatus = LoadStatus.DRAG_UP_TO_LAOD_MORE;
    private Presenter.RecyclerViewOnClickListener mOnItemClickListener;


    private RecyclerModule mForData = new RecyclerModule();

    public RecyclerAdapter(Context context, List<PartBean> list) {
        this.mContext = context;
        mInflater = LayoutInflater.from(context);
        this.mList = list;
    }

    @Override
    public int getItemCount() {
        return mList.size() + 1;
    }

    @Override
    public int getItemViewType(int position) {
        if (position + 1 == getItemCount()) {// 最后一条数据
            return VIEW_TYPE_FOOTER;
        } else {
            return VIEW_TYPE_ITEM;
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        switch (getItemViewType(position)) {
            case VIEW_TYPE_FOOTER:
                onBindFooterViewHolder(holder, position, mLoadStatus);
                break;
            case VIEW_TYPE_ITEM:
                onBindItemViewHolder(holder, position);
                break;
            default:
                break;
        }
    }

    private void onBindFooterViewHolder(RecyclerView.ViewHolder holder, int position,
                                        LoadStatus mLoadStatus2) {
        FooterViewHolder viewHolder = (FooterViewHolder) holder;
        switch (mLoadStatus2) {
            case DRAG_UP_TO_LAOD_MORE:
                viewHolder.mLoadingLayout.setVisibility(View.GONE);
                viewHolder.mClickLoad.setVisibility(View.VISIBLE);
                break;
            case LOADING_MORE:
                viewHolder.mLoadingLayout.setVisibility(View.VISIBLE);
                viewHolder.mClickLoad.setVisibility(View.GONE);
                break;
            case LOAD_FAILED:
                break;
            case LOAD_END:
                break;
        }
    }

    private void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
        ItemViewHolder viewHolder = (ItemViewHolder) holder;

        viewHolder.cardView.setName(mList.get(position).title);

    }

    // ===================onCreateHolder below==================
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_FOOTER) {
            return onCreateFooterViewHolder(parent, viewType);
        } else if (viewType == VIEW_TYPE_ITEM) {
            return onCreateItemViewHolder(parent, viewType);
        } else {
            return null;
        }
    }

    private RecyclerView.ViewHolder onCreateItemViewHolder(ViewGroup parent, int viewType) {

        AppMainCardView view = new AppMainCardView(mContext);
        return new ItemViewHolder(view, mOnItemClickListener);
    }

    private RecyclerView.ViewHolder onCreateFooterViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.item_footer, null);
        return new FooterViewHolder(view);
    }

    /**
     * 普通item的条目的holder
     *
     * @author administrator1
     */
    class ItemViewHolder extends RecyclerView.ViewHolder {

        private AppMainCardView cardView;

        private Presenter.RecyclerViewOnClickListener mListener;

        public ItemViewHolder(View view, Presenter.RecyclerViewOnClickListener listener) {
            super(view);
            cardView = (AppMainCardView) view;
            this.mListener = listener;
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mListener != null) {
                        int pos = getLayoutPosition();
                        v.setTag(mList.get(pos));
//                        mListener.onItemClicked(v, getPosition());// 应该用getlayoutposition?
                        mListener.onItemClicked(v, pos);// 应该用getlayoutposition?
                    }
                }
            });
        }
    }

    class FooterViewHolder extends RecyclerView.ViewHolder {
        public LinearLayout mLoadingLayout;
        public TextView mClickLoad;

        public FooterViewHolder(View itemView) {
            super(itemView);
            mLoadingLayout = (LinearLayout) itemView.findViewById(R.id.loading);
            mClickLoad = (TextView) itemView.findViewById(R.id.click_load_txt);
            mClickLoad.setOnClickListener(new View.OnClickListener() {// 添加点击加载更多监听
                @Override
                public void onClick(View v) {

                }
            });
        }
    }

    // ===========================method about data=========

    /**
     * 唯一的实现刷新效果的,就这两行语句实现刷新效果
     *
     * @param list
     */
    public void addAllNRefresh(List<PartBean> list) {
        this.mList.addAll(list);
        notifyDataSetChanged();
    }

    public void reSetData(List<PartBean> list) {
        this.mList = list;
        notifyDataSetChanged();
    }

    /**
     * 设置Adapter的状态并且刷新footer 被controller调用
     *
     * @param status
     */
    public void setLoadStatusNrefreshFooter(LoadStatus status) {
        this.mLoadStatus = status;
        this.notifyItemChanged(getItemCount() - 1);
    }

    public enum LoadStatus {
        DRAG_UP_TO_LAOD_MORE, // 点击加载更多
        LOADING_MORE, // 正在加载更多
        LOAD_FAILED, LOAD_END
    }

    /**
     * 设置点击事件
     *
     * @param listener
     */
    public void setOnItemClickListener(@NonNull Presenter.RecyclerViewOnClickListener listener) {
        mOnItemClickListener = listener;
    }

}
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.yds.tingli.MainApplication;
import com.yds.tingli.PlayActivity;

import java.util.List;

public class Presenter {
    ViewLayer mViewLayer;
    RecyclerModule mRecyclerModule = new RecyclerModule();

    public Presenter(ViewLayer viewLayer) {
        this.mViewLayer = viewLayer;
        /**
         * 设置加载更多的监听回调
         */
        mViewLayer.setOnNeedLoadListener(new PullUpRecyclerController.OnNeedLoadListener() {

            @SuppressWarnings("static-access")
            @Override
            public void loadMore(int from, int length) {
                Log.e("Presenter", "OnNeedloadMore");
                mRecyclerModule.loadMore(from, length,
                        new OnDataLoadedListener() {
                            @Override
                            public void onDataLoaded(
                                    final List<PartBean> cardViewBeanList) {
                                // 加载更多成功
                                ((Activity) (mViewLayer.context)).runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        mViewLayer.showMoreContent(cardViewBeanList);
                                        mViewLayer.setLoadStatusNrefreshFooter(RecyclerAdapter.LoadStatus.DRAG_UP_TO_LAOD_MORE);
                                    }
                                });

                            }

                            @Override
                            public void onDataLoadFailed(Throwable e) {
                                ((Activity) (mViewLayer.context)).runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        // 加载更多失败
                                        Toast.makeText(
                                                mViewLayer.getInnerView().getContext(),
                                                "未能读取到数据", Toast.LENGTH_SHORT).show();
                                        // mViewLayer.showError(e);
                                        mViewLayer.showLoadMoreFailure();
                                        mViewLayer.setLoadStatusNrefreshFooter(RecyclerAdapter.LoadStatus.DRAG_UP_TO_LAOD_MORE);
                                    }
                                });

                            }
                        });

            }
        });
    }

    /**
     * 方法名要改
     */
    public void onActivityCreate() {
        /**
         * 初始化module
         */
        // mModule = new Module1();
        loadData(0, Constance.ITEM_IN_A_PAGE);// 这个时候加载第一页
    }

    public void onActivityDestroy() {
        if (mRecyclerModule != null) {
            mRecyclerModule.cancelAll();
        }
    }


    /**
     * 在界面初始化的时候调用这个方法 这个方法会根据情况让显示层显示loading,content或者error
     */
    @SuppressWarnings("static-access")
    void loadData(int from, int length) {
        mViewLayer.showLoading();
        // load data from module and let view show them

        mRecyclerModule.loadMore(from, length, new OnDataLoadedListener() {

            @Override
            public void onDataLoaded(
                    final List<PartBean> cardViewBeanList) {
                // 第一次加载成功
                ((Activity) (mViewLayer.context)).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mViewLayer.showFirstPageContent(cardViewBeanList,
                                new RecyclerViewOnClickListener() {
                                    @Override
                                    public void onItemClicked(View view, int position) {
                                        //TODO 进入下一个页面
                                        Toast.makeText(mViewLayer.getInnerView().getContext(),
                                                "点击" + position, Toast.LENGTH_SHORT).show();
                                        PartBean bean = (PartBean) view.getTag();
                                        Intent intent = new Intent(
                                                MainApplication.getContext(),
                                                PlayActivity.class);

                                        intent.putExtra("bean", bean);
                                        ((Activity) (mViewLayer.context)).startActivity(intent);
                                    }
                                });
                    }
                });

            }

            @Override
            public void onDataLoadFailed(Throwable e) {
                // 第一次加载失败
                Toast.makeText(mViewLayer.getInnerView().getContext(),
                        "未能读取到数据", Toast.LENGTH_SHORT).show();
                mViewLayer.showError(e);
            }
        });


    }

    public interface OnDataLoadedListener {
        void onDataLoaded(List<PartBean> beanList);

        void onDataLoadFailed(Throwable e);
    }

    public interface RecyclerViewOnClickListener {
        void onItemClicked(View v, int position);// 应该用getlayoutposition?
    }
}

fraglayout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/errorView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="error"
        android:textSize="30dp" />

    <ProgressBar
        android:id="@+id/loadingView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:background="@color/white" />


</RelativeLayout>

itemfooter.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp">

    <LinearLayout
        android:id="@+id/loading"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="horizontal">

        <TextView
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="加载"
            android:textSize="30dp" />

        <ProgressBar
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <TextView
        android:id="@+id/click_load_txt"
        android:text="加载更多"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


</RelativeLayout>

mainitem.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="title" />

</RelativeLayout>

最后在activity中使用

Presenter mPresenter;
ViewLayer mViewLayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mViewLayer = new ViewLayer(this);
        mPresenter = new Presenter(mViewLayer);
        mPresenter.onActivityCreate();
        setContentView(mViewLayer.getInnerView());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mPresenter.onActivityDestroy();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值