Recylerview 加载更多功能实现(分页加载)

第一次写博客,表达可能不是很好,也是仅供初学的朋友们参考下,希望大家见谅。

Recyclerview是 Listview 的升级版本,在项目中使用较为广泛,官方也推荐我们使用 Recyclerview 来代替 Listview,在此就不多说 Recyclerview 的优势特点 balala了。。。

在实际项目中,列表通常是分页的,请求服务器也只会一次请求若干条,按需加载,这样比较节省流量,这样就有了我们很常见的下拉加载更多的功能,具体的实现效果如下图:

这里写图片描述

该activity的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.geek.loadmoredemo.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

底部加载更多的view:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:orientation="horizontal"
    android:padding="@dimen/activity_vertical_margin">

    <ProgressBar
       style="@android:style/Widget.Holo.ProgressBar.Small"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:text="正在加载..."/>

</LinearLayout>

数据item的view:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:tools="http://schemas.android.com/tools"
    android:padding="@dimen/activity_vertical_margin"
    android:orientation="horizontal">

    <ImageView
        android:src="@mipmap/ic_launcher"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <LinearLayout
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/title"
            android:gravity="center"
            tools:text="我是标题"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <TextView
            android:id="@+id/content"
            android:gravity="center"
            tools:text="我是内容"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</LinearLayout>

这里每次会加载10条数据,当列表滑动到最后一个已加载完成的item 时会出现加载更多的view并加载下10条数据。

在此都假设你已经熟悉了 Recylerview 的基本使用方法,分页的操作主要是在该 recyclerview 的 adapter 中实现的,代码如下:

package com.geek.loadmoredemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

import butterknife.Bind;
import butterknife.ButterKnife;

public class DemoAdapter extends RecyclerView.Adapter {
    private List<Demo> mDemos = new ArrayList<>();
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    private ILoadCallback mCallback;

    public DemoAdapter(Context context, List<Demo> list) {
        mContext = context;
        mLayoutInflater = LayoutInflater.from(context);
        addData(list);
    }

    //对外暴露设置接口方法
    public void setLoadCallback(ILoadCallback callback) {
        this.mCallback = callback;
    }

    public void addData(List<Demo> list) {
        mDemos.addAll(list);
        notifyDataSetChanged();//添加数据后通知 adpter 更新
    }

    @Override
    public int getItemViewType(int position) {
        if (position == mDemos.size()) {
            return R.layout.load_more_layout;
       } else {
            return R.layout.demo_item_layout;
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mLayoutInflater.inflate(viewType, parent, false);
        if (viewType == R.layout.load_more_layout) {
            return new LoadMoreVH(view);
        } else {
            return new DemoVH(view);
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof DemoVH) {
            ((DemoVH) holder).bind(mDemos, position);
        } else if (holder instanceof LoadMoreVH) {
            Log.d("loadmore", "loading...");
            mCallback.onLoad();
        }
    }

    @Override
    public int getItemCount() {
        return mDemos.size()+1;//recylerview的item的总数目是所有数据数量加一
    }

    //普通item的viewholder
    static class DemoVH extends RecyclerView.ViewHolder {

        @Bind(R.id.title)
        public TextView mTitle;
        @Bind(R.id.content)
        public TextView mContent;

        public DemoVH(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void bind(List<Demo> demo, int position) {
            mTitle.setText(demo.get(position).title);
            mContent.setText(demo.get(position).content);
        }
    }

    //底部加载更多item的viewholder
    static class LoadMoreVH extends RecyclerView.ViewHolder {

        public LoadMoreVH(View itemView) {
            super(itemView);
        }
    }

    //回调接口,用于回调加载数据的方法
    interface ILoadCallback {
        void onLoad();
    }

}

  1. 首先创建两个 ViewHolder类,继承RecyclerView.ViewHolder(使用 static 关键字修饰内部类就不会持有外部类的强引用,这样不会造成内存泄露问题),一个是需要展示的 item 的,一个是加载更多的 view 的。
  2. 然后重写 getItemType(int position)方法,判断如果position 是数据集合的最后一个,就返回加载更多的 view 的布局文件资源 ID,否则返回数据 item 的。
  3. 重写onCreateViewHolder(ViewGroup parent, int viewType)方法,在此方法中判断 viewType 不同,返回不同的 viewholder,这样就在 recylerview 创建 item 的时候会根据不同的 item 位置显示数据或者加载更多了。
  4. 重写onBindViewHolder(RecyclerView.ViewHolder holder, int position)方法,利用 instanceof 关键字判断 holder 对象是哪个的实例,如果是数据 item 的就执行绑定数据的操作;如果是加载更多 view 的就执行回调接口中的 onLoad()方法,将数据加载的具体逻辑交给外部处理。

该 Acitivity 代码如下:

package com.geek.loadmoredemo;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

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


public class MainActivity extends AppCompatActivity {

    RecyclerView mRecyclerView;

    private List<Demo> mDemos = new ArrayList<>();
    private DemoAdapter mAdapter;
    private Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intiData();
        initView();
    }

    private void intiData() {
        //首次加载数据
        for (int i = 0; i < 10; i++) {
            mDemos.add(new Demo("我是标题" + i, "我是内容" + i));
        }
    }

    private void initView() {
        mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        mAdapter = new DemoAdapter(this, mDemos);
        mAdapter.setLoadCallback(new DemoAdapter.ILoadCallback() {
            @Override
            public void onLoad() {
                mHandler.postDelayed(new Runnable() {//延时处理,模拟网络操作
                    @Override
                    public void run() {
                        List<Demo> demos = new ArrayList<Demo>();
                        for (int i = mDemos.size(); i < mDemos.size()+10; i++) {//每次请求10条数据
                            demos.add(new Demo("我是标题" + i, "我是内容" + i));
                        }
                        mAdapter.addData(demos);
                        mDemos.addAll(demos);
                    }
                }, 2000);
            }
        });//设置接口,实现加载数据的回调方法
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }
}

这样就完整实现了 Recylerview 的加载更多功能,总体来说还是很简单的,如果还是有不明白的,可能你对 Recylerview 的使用方法还不够了解,可以自行学习。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现分页Ajax无限加载功能,可以按照以下步骤进行: 1. 在WordPress主题中创建一个新的页面模板,命名为“ajax-pagination.php”(或者其他你喜欢的名字)。 2. 在模板中添加需要分页的内容。 3. 在模板中添加一个按钮或链接,用于加载多内容。 4. 使用jQuery编写Ajax代码,将按钮或链接与模板中的内容连接起来。 5. 在functions.php文件中添加一个新的函数,用于处理Ajax请求。 6. 编写一个新的WordPress查询,用于获取下一页的内容。 7. 将查询结果返回给Ajax请求,并将其添加到页面上。 以下是一个简单的示例代码,演示如何实现分页Ajax无限加载功能: 在ajax-pagination.php文件中,添加以下代码: ``` <div id="content"> <?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $args = array( 'post_type' => 'post', 'posts_per_page' => 3, 'paged' => $paged ); $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); // 输出文章内容 endwhile; endif; ?> </div> <div id="load-more"> <a href="#">加载多</a> </div> ``` 在JavaScript文件中,添加以下代码: ``` jQuery(document).ready(function($) { $('#load-more a').click(function() { var button = $(this), data = { 'action': 'load_more', 'query': loadmore_params.posts, 'page': loadmore_params.current_page }; $.ajax({ url: loadmore_params.ajaxurl, data: data, type: 'POST', beforeSend: function(xhr) { button.text('正在加载...'); }, success: function(data) { if (data) { button.text('加载多').prev().before(data); loadmore_params.current_page++; if (loadmore_params.current_page == loadmore_params.max_page) button.remove(); } else { button.remove(); } } }); return false; }); }); ``` 在functions.php文件中,添加以下代码: ``` add_action('wp_ajax_load_more', 'load_more'); add_action('wp_ajax_nopriv_load_more', 'load_more'); function load_more() { $query = json_decode(stripslashes($_POST['query']), true); $query['paged'] = $_POST['page'] + 1; $posts = new WP_Query($query); if ($posts->have_posts()) { while ($posts->have_posts()) { $posts->the_post(); // 输出文章内容 } } die; } ``` 以上代码仅仅是一个示例,你需要根据自己的实际情况进行修改和调整。但是,这个示例可以帮助你了解如何使用WordPress和Ajax来实现分页Ajax无限加载功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值