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

1参考学习

https://www.jianshu.com/p/90e9865181ec
对源代码进行了提升显示效果,和上文相似
原文地址https://blog.csdn.net/hongfei568718926/article/details/107606010

2运行效果

在这里插入图片描述

3代码实现

1代码结构

在这里插入图片描述

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疑惑寻找

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

5下载地址

https://github.com/ChenchaoDemo/Android_Recycler.git

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值