Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载

这篇具有很好参考价值的文章主要介绍了Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上拉、下拉的效果图如下:

Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载,androidAndroid 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载,android
使用步骤
  • 1、在清单文件中添加依赖

implementation ‘com.android.support:recyclerview-v7:27.1.1’
implementation “androidx.swiperefreshlayout:swiperefreshlayout:1.0.0”

Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载,android文章来源地址https://www.toymoban.com/news/detail-635731.html

  • 2、main布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:id="@+id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>
  • item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:gravity="center"
        android:textSize="20sp"
        android:textColor="#000000"
        android:text="11"
        android:layout_marginBottom="1dp"/>
</LinearLayout>
  • footview.xml(底部提示)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <TextView
        android:id="@+id/tips"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="20dp"
        android:textSize="15sp"
        android:layout_marginBottom="1dp"/>
</LinearLayout>
  • 2、MyAdapter
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private List<String> datas; // 数据源
    private Context context;    // 上下文Context

    private int normalType = 0;     // 第一种ViewType,正常的item
    private int footType = 1;       // 第二种ViewType,底部的提示View

    private boolean hasMore = true;   // 变量,是否有更多数据
    private boolean fadeTips = false; // 变量,是否隐藏了底部的提示

    private Handler mHandler = new Handler(Looper.getMainLooper()); //获取主线程的Handler

    public MyAdapter(List<String> datas, Context context, boolean hasMore) {
        // 初始化变量
        this.datas = datas;
        this.context = context;
        this.hasMore = hasMore;
    }

    // 获取条目数量,之所以要加1是因为增加了一条footView
    @Override
    public int getItemCount() {
        return datas.size() + 1;
    }

    // 自定义方法,获取列表中数据源的最后一个位置,比getItemCount少1,因为不计上footView
    public int getRealLastPosition() {
        return datas.size();
    }


    // 根据条目位置返回ViewType,以供onCreateViewHolder方法内获取不同的Holder
    @Override
    public int getItemViewType(int position) {
        if (position == getItemCount() - 1) {
            return footType;
        } else {
            return normalType;
        }
    }

    // 正常item的ViewHolder,用以缓存findView操作
    class NormalHolder extends RecyclerView.ViewHolder {
        private TextView textView;

        public NormalHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView.findViewById(R.id.tv);
        }
    }

    // // 底部footView的ViewHolder,用以缓存findView操作
    class FootHolder extends RecyclerView.ViewHolder {
        private TextView tips;

        public FootHolder(View itemView) {
            super(itemView);
            tips = (TextView) itemView.findViewById(R.id.tips);
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // 根据返回的ViewType,绑定不同的布局文件,这里只有两种
        if (viewType == normalType) {
            return new NormalHolder(LayoutInflater.from(context).inflate(R.layout.item, null));
        } else {
            return new FootHolder(LayoutInflater.from(context).inflate(R.layout.footview, null));
        }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
        // 如果是正常的imte,直接设置TextView的值
        if (holder instanceof NormalHolder) {
            ((NormalHolder) holder).textView.setText(datas.get(position));
        } else {
            // 之所以要设置可见,是因为我在没有更多数据时会隐藏了这个footView
            ((FootHolder) holder).tips.setVisibility(View.VISIBLE);
            // 只有获取数据为空时,hasMore为false,所以当我们拉到底部时基本都会首先显示“正在加载更多...”
            if (hasMore == true) {
                // 不隐藏footView提示
                fadeTips = false;
                if (datas.size() > 0) {
                    // 如果查询数据发现增加之后,就显示正在加载更多
                    ((FootHolder) holder).tips.setText("正在加载更多...");
                }
            } else {
                if (datas.size() > 0) {
                    // 如果查询数据发现并没有增加时,就显示没有更多数据了
                    ((FootHolder) holder).tips.setText("没有更多数据了");

                    // 然后通过延时加载模拟网络请求的时间,在500ms后执行
                    mHandler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            // 隐藏提示条
                            ((FootHolder) holder).tips.setVisibility(View.GONE);
                            // 将fadeTips设置true
                            fadeTips = true;
                            // hasMore设为true是为了让再次拉到底时,会先显示正在加载更多
                            hasMore = true;
                        }
                    }, 500);
                }
            }
        }
    }

    // 暴露接口,改变fadeTips的方法
    public boolean isFadeTips() {
        return fadeTips;
    }

    // 暴露接口,下拉刷新时,通过暴露方法将数据源置为空
    public void resetDatas() {
        datas = new ArrayList<>();
    }

    // 暴露接口,更新数据源,并修改hasMore的值,如果有增加数据,hasMore为true,否则为false
    public void updateList(List<String> newDatas, boolean hasMore) {
        // 在原有的数据之上增加新数据
        if (newDatas != null) {
            datas.addAll(newDatas);
        }
        this.hasMore = hasMore;
        notifyDataSetChanged();
    }

}
  • 3、MainActivity实现
public class MainActivity extends AppCompatActivity{
    private SwipeRefreshLayout refreshLayout;
    private RecyclerView recyclerView;
    private List<String> list;
    private int lastVisibleItem = 0;
    private final int COUNT = 10;
    private GridLayoutManager mLayoutManager;
    private MyAdapter adapter;
    private Handler mHandler = new Handler(Looper.getMainLooper());

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();//制造假数据
        initView();//初始化布局
        initRefreshLayout();//初始化下拉刷新
        initRecyclerView();//显示recyclerview布局

    }
    private void initData() {
        list = new ArrayList<>();
        for (int i = 1; i <= 40; i++) {
            list.add("测试" + i);
        }
    }
    private void initView() {
        refreshLayout = (SwipeRefreshLayout) findViewById(R.id.refreshLayout);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);

    }
    private void initRefreshLayout() {
        refreshLayout.setColorSchemeResources(android.R.color.holo_blue_light);
        refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {//上拉刷新,加载第一页
                refreshLayout.setRefreshing(true);
                adapter.resetDatas();
                updateRecyclerView(0, COUNT);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        refreshLayout.setRefreshing(false);
                    }
                }, 1000);
            }
        });
    }
    private void initRecyclerView() {
        adapter = new MyAdapter(getDatas(0, COUNT), this, getDatas(0, COUNT).size() > 0 ? true : false);
        mLayoutManager = new GridLayoutManager(this, 1);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setAdapter(adapter);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    if (adapter.isFadeTips() == false && lastVisibleItem + 1 == adapter.getItemCount()) {
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                updateRecyclerView(adapter.getRealLastPosition(), adapter.getRealLastPosition() + COUNT);
                            }
                        }, 500);
                    }
                    if (adapter.isFadeTips() == true && lastVisibleItem + 2 == adapter.getItemCount()) {
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                updateRecyclerView(adapter.getRealLastPosition(), adapter.getRealLastPosition() + COUNT);
                            }
                        }, 500);
                    }
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                lastVisibleItem = mLayoutManager.findLastVisibleItemPosition();
            }
        });
    }
    private void updateRecyclerView(int fromIndex, int toIndex) {
        List<String> newDatas = getDatas(fromIndex, toIndex);
        if (newDatas.size() > 0) {
            adapter.updateList(newDatas, true);
        } else {
            adapter.updateList(null, false);
        }
    }

    //拿到全部数据,加载
    private List<String> getDatas(final int firstIndex, final int lastIndex) {
        List<String> resList = new ArrayList<>();
        for (int i = firstIndex; i < lastIndex; i++) {
            if (i < list.size()) {
                resList.add(list.get(i));
            }
        }
        return resList;
    }
    
}

到了这里,关于Android 实现 RecyclerView下拉刷新,SwipeRefreshLayout上拉加载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uniapp使用自带【刷新方法】与使用【scroll-view】实现下拉刷新上拉加载

    前言:uniapp自带下拉刷新,上拉加载功能基本可以满足刷新需求,但是顶部有状态栏的页面就得进行特殊处理,使用scroll-view解决,状态栏会连带被下拉问题   1、uniapp自带下拉刷新、上拉加载 在page.json中对应页面路由设置【enablePullDownRefresh】值为true(开启下拉刷新) 代码:

    2024年02月11日
    浏览(33)
  • van-list van-pull-refresh实现上拉加载,下拉刷新

    背景:在移动端项目开发中有列表页面开发,需要实现上拉加载下一页数据,下拉刷新页面。 Vant 是一个轻量、可靠的移动端组件库,使用该框架的van-list组件和van-pull-refresh组件可实现上述功能 van-list组件 :瀑布流滚动加载,用于展示长列表,当列表即将滚动到底部时,会触

    2024年02月15日
    浏览(33)
  • 【Flutter】Flutter 使用 pull_to_refresh 实现下拉刷新和上拉加载

    【Flutter】Flutter 使用 pull_to_refresh 实现下拉刷新和上拉加载 你好!在移动开发中,下拉刷新和上拉加载是非常常见的功能。 今天,我将为你介绍一个非常实用的 Flutter 包—— pull_to_refresh 。在这篇文章中,我们将学习如何使用这个包,以及如何在实际业务中应用它。 文章的重

    2024年02月07日
    浏览(30)
  • uniapp开发使用插件z-paging实现页面下拉刷新、上拉加载,分页加载

    在uniapp官网有一个比较好用的插件z-paging,可以实现多条数据滚动显示或者自定义下拉刷新,分页显示......在开发消息页面或者app开发需要大量的页面刷新,页面内容过长,减轻服务器的负担就可以使用此插件,进入app智慧加载部分内容,等到再次需要之后的内容就再次加载

    2024年02月11日
    浏览(40)
  • 小程序 uniApp 下拉刷新 上拉加载

    在小程序和uniapp 中 可以通过 scrooll-view / 这个组件来实现 下拉刷新 和 上拉加载的功能 。官方文档 通过配置 scroll-x 和 scroll-y 可以实现 横向 或纵向的滚动 下拉刷新 配置 refresher-enabled 开启自定义下拉刷新 配置 refresher-triggered 设置下拉刷新的状态 (true 表示下拉刷新已经被触

    2024年02月05日
    浏览(42)
  • 微信小程序 上列表拉加载下拉刷新

      上拉加载和下拉刷新是小程序开发的常见需求。本文将介绍如何在微信小程序中实现上拉加载和下拉刷新的功能,为用户带来更加流畅、便捷的使用体验。 微信小程序 上列表拉加载下拉刷新 (1) 首先需要在使用到的 json 文件下配置 “enablePullDownRefresh”: true (2) 在 js 文件

    2024年01月16日
    浏览(41)
  • 微信小程序-上拉加载更多和下拉刷新

    页面配置文件中配置 \\\"enablePullDownRefresh\\\": true 开启下拉刷新 设置 onPullDownRefresh 方法 在用户下拉时会调用 onPullDownRefresh 方法 在完成后需要调用 wx.stopPullDownRefresh() 关闭刷新状态 可以在页面配置文件中配置 \\\"onReachBottomDistance\\\":50 来设置触发上拉加载的距离,单位为 px 。 默认:

    2024年02月15日
    浏览(33)
  • H5如何做页面下拉刷新和上拉加载

    这里以vant为例 结构 处理方法

    2024年02月10日
    浏览(36)
  • Flutter 库:强大的下拉刷新上拉加载框架——EasyRefresh

    EasyRefresh 是一个用于 Flutter 应用程序的简单易用的 下拉刷新 和 上拉加载 框架。它支持几乎所有的 Flutter 可滚动小部件。它的功能与Android 的 SmartRefreshLayout 非常相似,并吸收了许多第三方库的优点。EasyRefresh 集成了各种样式的页眉和页脚,但没有任何限制,您可以轻松自定

    2024年01月19日
    浏览(29)
  • 微信小程序 下拉分页 z-paging下拉刷新、上拉加载

    【z-paging下拉刷新、上拉加载】高性能,全平台兼容。支持虚拟列表,支持nvue、vue3 - DCloud 插件市场  z-paging,使用非常简单,按部就班就行了 1,首先将其导入自己的小程序项目中  导入后的效果 2,具体如何使用:https://z-paging.zxlee.cn    选项式api写法(vue2/vue3) 组合式api写法

    2024年02月11日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包