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("\t\t" + 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();

    }
}

原文地址:https://www.cnblogs.com/guanxinjing/p/10299889.html

时间: 2024-11-02 17:25:44

Android 开发 上拉加载更多功能实现的相关文章

android ListView上拉加载更多 下拉刷新功能实现(采用pull-to-refresh)

Android实现上拉加载更多功能以及下拉刷新功能, 采用了目前比较火的PullToRefresh,他是目前实现比较好的下拉刷新的类库. 目前他支持的控件有:ListView, ExpandableListView,GridView,WebView等. 下载地址:https://github.com/chrisbanes/Android-PullToRefresh 首先第一步当然是导入libriay到咱们的项目了,具体导入方式,这里不再赘述. 下面是个例子采用的是ListView,当然其余的和这

Android实战简易教程-第五十三枪(通过实现OnScrollListener接口实现上拉加载更多功能)

支持上拉加载更多的控件有很多,但是你知道背后的原理吗?有一些面试官可能会问到这方便的知识,他们认为会用不是目的,懂背后的原理才是真人才.下面我们通过实现OnScrollListener接口实现上拉加载更多的效果,这里用到了回调接口,你需要对回调进行比较好的理解,回调机制是Android中很重要的机制,下面我们看一下代码: 1.定义一个footer.xml,用于下拉提示的效果: <?xml version="1.0" encoding="utf-8"?>

7-5 高级功能列表下拉刷新与上拉加载更多功能实现

数组还是那个数组,只不过这里由静态类型改成了非静态类型. 改成了有状态的widget 用RefreshIndicator包裹ListView.这样ListView就有了下拉刷新的能力. 下拉,松开的的手的时候会执行刷新,也就是onRefresh这个方法.这个方法要求我们传递一个必须带有Future返回值的方法 所以这里我们定义了带有Future返回值的方法.这个方法里面如果我们不想返回值的内容,就在Future的泛型设置为Null.也就是Future<Null> 下拉刷新的方法,延迟2秒钟,修

android 安卓 listview 支持下拉刷新 上拉加载更多

[1]重写listView import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGrou

Android5.0新特性:RecyclerView实现上拉加载更多

RecyclerView是Android5.0以后推出的新控件,相比于ListView可定制性更大,大有取代ListView之势.下面这篇博客主要来实现RecyclerView的上拉加载更多功能. 基本思路是让RecyclerView的Adapter加载两种布局,第一个布局来显示主界面,第二个布局来显示上拉加载时的提示信息,让RecyclerView监听是否滑动到最后一个item,如果是,则调用上拉刷新的逻辑,拉取远程数据,并显示第二个布局.等加载完毕时,刷新 Adapter,并隐藏第二个布局.

IOS-给UIScrollView(包括继承它的UITableView、UICollectionView)添加下拉刷新-上拉加载更多

IOS里面用到的下拉刷新.上拉加载更多控件,开源的第三方框架很多,我们可以直接拿过来用,别人造好的轮子我们就没有必要再造一遍了,这里推荐几款下拉刷新.上拉加载更多控件 只有下拉刷新的: 一.EGOTableViewPullRefresh 这个使用起来比较麻烦,需要实现其各种协议,github地址为: https://github.com/enormego/EGOTableViewPullRefresh 这个貌似有个扩展上拉加载更多的,有时间补上 二.PullToRefresh  这个使用起来比E

Android中ListView上拉加载更多及下拉刷新

做几乎每一个Android应用开发,都少不了用到一个控件,那就是ListView,用于加载多条数据,并用一定的样式展示出来.但是为了性能问题(一次性加载太多数据,比如100000条,耗费时间长,消耗资源多等)及用户体验问题(比如用户只想看最新的10条数据,结果一下子把所有的上万条数据都加载了,不方便用户选择)等原因,所以我们要把ListView的数据进行分页加载,常用的就是ListView的上拉加载更多及下拉刷新最新数据. 我们可以自己封装一个带上下拉功能的ListView,通常就是加上头部He

Android上拉加载更多ListView——PulmListView

思路 今天带大家实现一个上拉加载更多的ListView.GitHub传送门:PulmListView, 欢迎大家fork&&star. 先带大家理一下思路, 如果我们要实现一个上拉加载更多的ListView, 我们需要实现的功能包括: 一个自定义的ListView, 并且该ListView能够判断当前是否已经处于最底部. 一个自定义的FooterView, 用于在ListView加载更多的过程中进行UI展示. 关联FooterView和ListView, 包括加载时机判断.FooterVi

Android中自定义ListView实现上拉加载更多和下拉刷新

ListView是Android中一个功能强大而且很常用的控件,在很多App中都有ListView的下拉刷新数据和上拉加载更多这个功能.这里我就简单记录一下实现过程. 实现这个功能的方法不止一个,GitHub上有一些开源库可以使用,但是本着学习的精神,我做的是使用自定义ListView实现这个功能. 思路:谷歌提供的ListView是不能提供下拉刷新和下拉加载的,所以我们就需要重写ListView.在ListView的头部和尾部加上我们的布局文件(progressbar). 先说上拉加载更多实现