RecyclerView(2)实现列表,可刷新,向上滑动可以加载更多
程序员文章站
2022-05-12 08:42:12
...
1参考学习
https://www.jianshu.com/p/90e9865181ec
对源代码进行了提升显示效果,和上文相似
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疑惑寻找
添加按钮不能实现监听每一个列表项目,这个暂时还没实现,等我学习一波,解决了我会在后面加入的.有思路的小伙伴可以在评论区进行分享,谢谢