欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RecyclerView(2)实现列表,可刷新,向上滑动可以加载更多

程序员文章站 2022-05-12 08:42:12
...

1参考学习

https://www.jianshu.com/p/90e9865181ec
对源代码进行了提升显示效果,和上文相似

2运行效果

RecyclerView(2)实现列表,可刷新,向上滑动可以加载更多

3代码实现

1代码结构

RecyclerView(2)实现列表,可刷新,向上滑动可以加载更多

2布局文档

需要先加入RecyclerView包,不知道如何导入参考
https://blog.csdn.net/hongfei568718926/article/details/107559107

布局文件代码顺序对应代码结构顺序
布局1

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

    <android.support.v4.widget.SwipeRefreshLayout
        android:id="@+id/swipeRefreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <com.example.chen.recyclerview2.MyRecyclerView
            android:id="@+id/myRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />
    </android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>

布局2

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >
    <ImageView
        android:id="@+id/item_imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/item_textView1"
            android:layout_width="wrap_content"
            android:layout_height="20dp"
            />
        <TextView
            android:id="@+id/item_textView2"
            android:layout_width="wrap_content"
            android:layout_height="20dp" />
    </LinearLayout>
</LinearLayout>

布局3

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root_footer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="15dp">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal">

        <ProgressBar
            android:layout_marginTop="10dp"
            android:id="@+id/progressBar1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginLeft="15dp"
            android:text="加载更多"
            android:textSize="14sp" />
    </LinearLayout>
</FrameLayout>

3类的实现

代码文件顺序结构对应于项目代码结构
MainActivity

package com.example.chen.recyclerview2;

import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;

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

public class MainActivity extends AppCompatActivity implements OnFooterAutoLoadMoreListener{
    private SwipeRefreshLayout swipeRefreshLayout;
    private MyRecyclerView myRecyclerView;
    private List<Model> modelList=new ArrayList<>();
    private MyAdapter myAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //SwipeRefreshLayout布局
        swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipeRefreshLayout);
        myRecyclerView=(MyRecyclerView)findViewById(R.id.myRecyclerView);
        myRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        myRecyclerView.addFooterAutoLoadMoreListener(this);
        myAdapter=new MyAdapter(modelList);
        myRecyclerView.setAdapter(myAdapter);
        loadMore();//加载数据
        ///设置手势滑动监听器。
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //刷新数据
                myAdapter.notifyAllDatas(modelList,myRecyclerView);
                modelList.clear();
                modelList.addAll(Model.getData());
                //设置组件的刷新状态false代表停止执行,这样,
                //当我们执行完毕获取数据的过程后,就可以将一直转的下拉动画给取消掉啦
                swipeRefreshLayout.setRefreshing(false);
            }
        });
    }

    @Override
    public void loadMore() {
        myAdapter.notifyAllDatas(modelList,myRecyclerView);//刷新数据
        List<Model> list=Model.getData();
        modelList.addAll(list);
        swipeRefreshLayout.setRefreshing(false);//初次要停止刷新
    }
}

Model

package com.example.chen.recyclerview2;

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

/**
 * Created by Chen on 2020/7/24.
 */

//定义一个Model,用于模拟数据加载
public class Model {
    private String textView1;
    private String textView2;
    private int imageId;
    public Model(String text1,String text2,int image){
        this.textView1=text1;
        this.textView2=text2;
        this.imageId=image;
    }

    public String getTextView1() {
        return textView1;
    }

    public void setTextView1(String textView1) {
        this.textView1 = textView1;
    }

    public String getTextView2() {
        return textView2;
    }

    public void setTextView2(String textView2) {
        this.textView2 = textView2;
    }

    public int getImageId() {
        return imageId;
    }

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }
    //获取数据
    public static List<Model> getData(){
        List<Model> Modellist=new ArrayList<>();
        for(int i=0;i<30;i++){
            Model model=new Model("大标题"+i,"小标题"+i,R.drawable.image);
            Modellist.add(model);
        }
        return Modellist;
    }
}

MyAdapter

package com.example.chen.recyclerview2;

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.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import static com.example.chen.recyclerview2.MyRecyclerView.VIEW_TYPE_FOOTER;
import static com.example.chen.recyclerview2.MyRecyclerView.VIEW_TYPE_NOMAL;

/**
 * Created by Chen on 2020/7/24.
 */

public class MyAdapter  extends RecyclerView.Adapter<MyViewHolder> {
    private List<Model> modelList;//数据list
    private static final String TAG="MyAdapter";
    public MyAdapter(List<Model> list) {
        this.modelList = list;
    }

    /**
     * 返回view类型
     *
     * @param position
     * @return
     */
    @Override
    public int getItemViewType(int position) {
        Log.e(TAG,"position:"+position);
        Log.e(TAG,"getItemViewType");
        if (position == getItemCount() - 1)//如果是最后一个item,则是底部布局
            return VIEW_TYPE_FOOTER;//末尾的item
        return VIEW_TYPE_NOMAL;  //正常item
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.e(TAG,"onCreateViewHolder");
        if (viewType == VIEW_TYPE_FOOTER)
            return MyViewHolder.createViewHolder(parent, R.layout.item_root_footer);//返回底部布局
        return MyViewHolder.createViewHolder(parent, R.layout.item_normal); //返回正常item
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
        Log.e(TAG,"onBindViewHolder");
        int viewType = getItemViewType(position);
        if (viewType == VIEW_TYPE_NOMAL) {//正常item需要绑定数据
            TextView textView1=holder.getView(R.id.item_textView1);
            textView1.setText(modelList.get(position).getTextView1());
            TextView textView2=holder.getView(R.id.item_textView2);
            textView2.setText(modelList.get(position).getTextView2());
            ImageView imageView=holder.getView(R.id.item_imageView);
            imageView.setImageResource(modelList.get(position).getImageId());
        }
        //添加监听事件

//        myViewHolder.ParentView.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                Toast.makeText(view.getContext(),"你点击了"+modelList.get(position).getTextView1(),Toast.LENGTH_SHORT).show();
//
//            }
//        });

    }

    /**
     * 返回item的数量
     * 因为在原有数据数量基础上加了一个底部布局,所以总的item数量应该+1
     * @return
     */
    @Override
    public int getItemCount() {
        int count = modelList.size();
        count++;
        return count;
    }

    /**
     * 刷新数据
     * @param mList
     */
    public void notifyAllDatas(List<Model> mList,MyRecyclerView recyclerView) {
        this.modelList = mList;
        recyclerView.post(new Runnable() {
            @Override
            public void run() {
                notifyDataSetChanged();
            }
        });
    }
}

MyRecyclerView

package com.example.chen.recyclerview2;

import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;

/**
 * Created by Chen on 2020/7/24.
 */

public class MyRecyclerView extends RecyclerView {
    private static final String TAG="MyRecyclerView";
    private OnFooterAutoLoadMoreListener listener;//监听底部
    public static final int VIEW_TYPE_NOMAL = 0;//item的类型-正常的item
    public static final int VIEW_TYPE_FOOTER = 200;//item的类型-底部的数量

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

    public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        addOnScrollListener(mOnScrollListener);//添加底部加载接口
    }

    /**
     * 滑动监听
     * 滑动到最后一个item的底部时加载更多信息
     */
    private OnScrollListener mOnScrollListener = new OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if(!canScrollVertically(1)){
                if (listener != null) {
                    listener.loadMore();
                }
            }
        }
    };
    /**
     * 添加底部加载接口
     * @param listener
     */
    public void addFooterAutoLoadMoreListener(OnFooterAutoLoadMoreListener listener){
        this.listener=listener;
    }
}

MyViewHolder

package com.example.chen.recyclerview2;

import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import java.util.List;

/**
 * Created by Chen on 2020/7/24.
 */

public class MyViewHolder extends RecyclerView.ViewHolder{


    //SparseArray用于以键值对的方式存储view,形成一个id与一个view对应
    private SparseArray<View> mHolderView;//缓存子控件View
    public  View ParentView;    //最外层view

    public MyViewHolder(View itemView) {
        super(itemView);
        this.ParentView=itemView;

        if(mHolderView==null){
            mHolderView=new SparseArray<>();
        }
    }


    /**
     * 根据layoutID创建ViewHolder
     * @param parent
     * @param layoutId
     * @return
     */
    public static MyViewHolder createViewHolder(ViewGroup parent, int layoutId){
        View view= LayoutInflater.from(parent.getContext()).inflate(layoutId,parent,false);
        return new MyViewHolder(view);
    }

    /**
     * 根据View创建viewHolder
     * @param view
     * @return
     */
    public static MyViewHolder createViewHolder(View view){
        return new MyViewHolder(view);
    }

    /**
     * 获取View
     * @param id
     * @param <T>
     * @return
     */
    public <T extends View> T getView(int id){
        View view=mHolderView.get(id);
        if(view==null){
            view=ParentView.findViewById(id);
            mHolderView.put(id,view);
        }
        return (T) view;
    }
}

OnFooterAutoLoadMoreListener 接口

package com.example.chen.recyclerview2;

/**
 * Created by Chen on 2020/7/24.
 *  底部监听接口
 */

public interface OnFooterAutoLoadMoreListener {
    /**
     * 加载更多数据
     */
    void loadMore();

}

4疑惑寻找

添加按钮不能实现监听每一个列表项目,这个暂时还没实现,等我学习一波,解决了我会在后面加入的.有思路的小伙伴可以在评论区进行分享,谢谢