Android 开发 上拉加载更多功能实现

Posted 观心静

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 开发 上拉加载更多功能实现相关的知识,希望对你有一定的参考价值。

实现思维

  开始之前先废话几句,android系统没有提供上拉加载的控件,只提供了下拉刷新的SwipeRefreshLayout控件。这个控件我们就不废话,无法实现上拉刷新的功能。现在我们说说上拉加载更多的功能实现

 

 思维步骤:

  1. 首先需要创建一个叫页尾的布局文件,它用来在列表的最后面显示使用
  2. 接着我们需要想办法在RecyclerView的适配器里导入这个页尾布局。你的列表内容适配器的普通item该如何实现还是如何实现。
  3. 为了导入这个页尾布局,我们需要在导入的List长度+1,因为这个页尾布局是另外加入的,需要在getItemCount()这个重写方法里返回List长度上+1。
  4. 现在就需要判断什么时候滚动到了列表的最后,这个时候我们需要重写一个之前写RecyclerView适配器一般不触及的一个重写方法public int getItemViewType(int position) 。重写它根据position位置返回普通item和页尾item的ViewType。
  5. 能判断什么时候滚动到最后面后,我们就需要在写RecyclerView适配器一样在onCreateViewHolder方法里导入布局,这里我们可以根据ViewType判断应该导入普通item还是页尾item
  6. 然后就是处理点击逻辑或者处理刷新逻辑了。这部分就不在详细描述步骤了。看下面的代码

  

代码部分

页尾布局 pull_up_refresh.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/colorGray5"
    android:layout_width="match_parent"
    android:layout_height="30dp">

    <ProgressBar
        android:id="@+id/footer_progress"
        android:layout_width="14dp"
        android:layout_height="14dp"
        android:layout_marginRight="10dp"
        android:visibility="gone"
        android:indeterminateDrawable="@anim/pull_up_ic"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@id/footer_text"
        app:layout_constraintBottom_toBottomOf="@id/footer_text"
        app:layout_constraintRight_toLeftOf="@id/footer_text"/>

    <TextView
        android:id="@+id/footer_text"
        android:text="@string/pull_up_load_more"
        android:textColor="@color/fontBlack3"
        android:textSize="@dimen/font_size_14"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toRightOf="@id/footer_progress"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
ProgressBar是刷新加载时候的动画图片  TextView就是文本内容

适配器代码:

public class TNoticeListAdapter extends RecyclerView.Adapter<TNoticeListAdapter.ViewHolder> {
    private List<TNoticeListBase.Notice> mList;
    private static final int ITEM_VIEW = 1;
    private static final int FOOTER_VIEW = 2;
    public static final int FOOTER_TIPS = 0;//提示上拉加载更多
    public static final int FOOTER_ING = 1;//加载中
    public static final int FOOTER_ERROR = 2;//网络异常
    public static final int FOOTER_FINISH = 3;//没有更多内容
    private int footerState = 0;
    private View mFooterView;
    private OnFooterClickListener mListener;
    private int position;
    public TNoticeListAdapter(List<TNoticeListBase.Notice> list){
        this.mList = list;

    }
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == ITEM_VIEW){
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.t_notice_item,parent,false);
            return new ViewHolder(itemView);
        }else {
            mFooterView = LayoutInflater.from(parent.getContext()).inflate(R.layout.pull_up_refresh,parent,false);
            mFooterView.setOnClickListener(new View.OnClickListener() {//页尾View只在网络异常的时候可以被点击
                @Override
                public void onClick(View v) {
                    if (getFooterState()==FOOTER_ERROR && mListener!=null){
                        mListener.onClick();
                    }

                }
            });
            return new ViewHolder(mFooterView);

        }
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        setPosition(position);
        if (getItemViewType(position) == ITEM_VIEW) {
            TNoticeListBase.Notice data = mList.get(position);
            holder.itemTime.setText(String.valueOf(data.time));
            holder.itemContent.setText("		" + data.content);
            return;
        }
        if (getItemCount()<10){ //如果传入的list内容少于10 就判断为服务器里没有更多内容了
            this.footerState = FOOTER_FINISH;
        }
        switch (footerState){
            case FOOTER_TIPS:
                holder.footerText.setText(R.string.pull_up_load_more);
                holder.footerProgress.setVisibility(View.GONE);
                break;
            case FOOTER_ING:
                holder.footerText.setText(R.string.loading_more_for_you);
                holder.footerProgress.setVisibility(View.VISIBLE);
                break;
            case FOOTER_ERROR:
                holder.footerText.setText(R.string.network_exception_click_reload);
                holder.footerProgress.setVisibility(View.GONE);
                break;
            case FOOTER_FINISH:
                holder.footerText.setText(R.string.Theres_nothing_more);
                holder.footerProgress.setVisibility(View.GONE);
                break;
            default:
                holder.footerText.setText(R.string.pull_up_load_more);
                holder.footerProgress.setVisibility(View.GONE);
                break;
        }
    }

    @Override
    public int getItemViewType(int position) {
        //根据itemView的位置返回View的类型是普通还是页尾
        if (position == getItemCount()-1){
            return FOOTER_VIEW;
        }else {
            return ITEM_VIEW;
        }
    }

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

    /**
     * 得到页尾状态
     * @return
     */
    public int getFooterState() {
        return footerState;
    }

    /**
     * 设置页尾状态
     * @param footerState
     */
    public void setFooterState(int footerState) {
        this.footerState = footerState;
        notifyDataSetChanged();
    }

    /**
     * 设置页尾点击监听
     * @param listener
     */
    public void setFooterClickListener(OnFooterClickListener listener){
        this.mListener = listener;

    }

    /**
     * 添加数据方法
     * @param list
     */
    public void addData(List<TNoticeListBase.Notice> list){
        this.mList = list;

    }

    /**
     * 获取当前位置
     * @return
     */
    public int getPosition() {
        return position;
    }

    private void setPosition(int position) {
        this.position = position;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        TextView itemTime;
        TextView itemContent;
        TextView footerText;
        ProgressBar footerProgress;
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            if (mFooterView!=null && itemView == mFooterView){
                footerProgress = (ProgressBar)itemView.findViewById(R.id.footer_progress);
                footerText = (TextView)itemView.findViewById(R.id.footer_text);
            }else {
                itemTime = (TextView) itemView.findViewById(R.id.time);
                itemContent = (TextView) itemView.findViewById(R.id.content);
            }
        }
    }

    public interface OnFooterClickListener{
        void onClick();

    }
}

 

以上是关于Android 开发 上拉加载更多功能实现的主要内容,如果未能解决你的问题,请参考以下文章

Android RecyclerView上拉加载更多item点击事件(显示获取的数据)

Android上拉加载更多ListView——PulmListView

Android开发之头部悬浮的上拉加载,下拉刷新的列表

移动端touch事件 || 上拉加载更多

Android实现RecyclerView的下拉刷新和上拉加载更多

[Android] Android 支持下拉刷新上拉加载更多 的 XRecyclerview