自带刷新的列表-LtRecyclerView v2.x版本(LtAdapter)

180 阅读8分钟

LtRecyclerView2.x版本比1.x版本多了几个好用的功能,很实用 总体功能:

  1. 带有上拉加载和下拉刷新和回调
  2. 设置条目点击事件和条目长按事件
  3. 添加头布局和尾布局
  4. 添加没条目时展示的View(或者添加没条目和有条目时的回调事件)
  5. 添加分割线(也可以用图片)
  6. 自定义上拉加载的View
  7. 自定义下拉刷新的View(包括RecyclerView移动和不移动),而且非常简单
  8. 仅需修改一行代码即可更改所有的刷新View
  9. 可单独使用下拉刷新View

图示:

使用:

远程仓库引用:

在根项目的build.gradle文件中加入:

allprojects {
    repositories {
...
        maven { url 'https://jitpack.io' }
    }
}

需要添加的地方加入:

implementation 'com.github.ltttttttttttt:ltviews:3.2.0'//androidx
//下面的是support包中的,已被废弃,全面改用androidx包
implementation 'com.github.ltttttttttttt:ltviews:2.3.9'//android support 以后不再进行更新

正式使用

2.xml布局文件中:

    <com.lt.ltviews.lt_recyclerview.LTRecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:dividerHeight="1dp" //设置分割线的高度,默认颜色是#d5d5d5
            app:noItemText="暂无数据" //设置没有数据时展示的文字 />

3.java代码使用示例,只需要set一个适配器和加一个加载的回调即可

rv = (LTRecyclerView) findViewById(R.id.rv);
        //创建一个适配器
        LtAdapter adapter = new LtAdapter() {
            @Override
            public RecyclerView.ViewHolder onLtCreateViewHolder(ViewGroup parent, int viewType) {
                //在这里返回一个ViewHolder,构造里放需要展示的View
                return new RecyclerView.ViewHolder(new TextView(getApplicationContext())) {
                };
            }

            @Override
            public int getLtItemCount() {
                //适配器展示多少条数据
                return 100;
            }

            @Override
            public void onLtBindViewHolder(RecyclerView.ViewHolder holder, int position) {
                //给View设置数据
                ((TextView) holder.itemView).setText("" + position);
            }
        };
        adapter.setOnRvItemClickListener(new OnRvItemClickListener() {
            @Override
            public void onItemClick(View itemView, int position) {
                //条目的点击事件
            }
        });
        rv.setAdapter(adapter)
                .setOnUpAndDownListener(new OnUpAndDownListener() {
                    @Override
                    public void up() {
                        //上拉加载时的回调
                    }

                    @Override
                    public void down() {
                        //下拉刷新时的回调
                    }
                });
        //设置每行有多少个条目,默认是1
        rv.setSpanCount(3);

4.设置刷新状态的方法

        rv.setTopRefresh(false);//设置是否下拉刷新
        rv.setBottomRefresh(false);//设置是否上拉加载
        rv.notifyDataSetChanged();//刷新数据源(更新条目)

5.Kotlin加持适配器(使用Kotlin语言可用),现在已经封装进来,ps:最新版封装的kt适配器文章:超级封装RecyclerView的适配器Adapter 只需二三十行代码_滔lt的博客-CSDN博客

继承BaseLtAdapterOneType或BaseLtAdapterOneType使用

class MAdapter(list: ArrayList<InfoBean>) : BaseLtAdapterOneType<InfoBean>(list, item_layout的id) {
    override fun setData(h:BaseLtViewHolder, b: InfoBean, i: Int) {
        h.tvTitle.text=b.title//直接使用item的view内的id,然后使用bean类的属性赋值,i为position,h为viewholder(为了简单写,所以都用了单个字母的简写)
        //使用该功能需要在对应的model的gradle的android{}中加入下面代码,老版的最大版本为2.7.0(已不再维护老版本,因为性能没有这个高)
        //   androidExtensions {
        //       experimental = true
        //   }
    }
}

甚至可以直接这样快捷使用适配器,这么两行就相当于条目4里java代码里的一堆

rv.adapter = ltAdapterOf(mutableListOf(""), 0) {h, b, i ->  
   
}

混淆

-keep class com.lt.ltviewsx.** { *;}

6.设置上拉加载和下拉刷新和回调

        rv.setOnUpAndDownListener(new OnUpAndDownListener() {
                    @Override
                    public void up() {
                        //上拉加载时的回调
                    }

                    @Override
                    public void down() {
                        //下拉刷新时的回调
                    }
                });

        //禁用上拉加载:new适配器的时候传null
        new LtAdapter(null);
        //禁用下拉刷新:获取刷新View,并设置为不可用
        rv.getRefreshLayout().setEnabled(false);

7.设置条目点击事件和条目长按事件(在onLtBindViewHolder()方法中设置点击或长按事件优先级大于该方法)

        adapter.setOnRvItemClickListener(new OnRvItemClickListener() {
            @Override
            public void onItemClick(View itemView, int position) {
                //条目的点击事件
            }
        });
        adapter.setOnRvItemLongClickListener(new OnRvItemLongClickListener() {
            @Override
            public void onItemLongClick(View itemView, int position) {
                //条目的长按事件     
            }
        });

8.添加头布局和尾布局

        //添加头布局
        adapter.addHeadView(View);
        //添加头布局到指定位置,注意可能会数组越界异常
        adapter.addHeadView(View, 0);
        //获取头布局的集合
        adapter.getHeadList()
        
        //添加尾布局(添加到最下面)
        adapter.addTailView(View);
        //添加尾布局到指定位置,注意可能会数组越界异常
        adapter.addTailView(View, 0);
        //获取尾布局的集合
        adapter.getTailList()

9.添加没条目时展示的View(或者添加没条目和有条目时的回调事件)

        //设置没数据时展示的TextView
        rv.setNoItemText("暂无数据");
        //设置没数据时展示的View
        rv.setNoItemView(View);
        
        //没有条目时的回调
        adapter.addOnNoItemListener(new OnNoItemListener() {
            @Override
            public void noItem() {
                //从有数据变为没有数据时触发
            }

            @Override
            public void haveItem() {
                //从没有数据变为有数据是触发
            }
        });

            app:noItemText="暂无数据"//设置没有数据时展示的TextView
            app:noItemView="@drawable/ic_launcher"//设置没数据时展示的View

注意:app:noItemText和noItemView两个方法不能同时设置

setHeadersIsItem(boolean)//头布局算不算在条目内(用于noItem算法)setTailsIsItem(boolean)//头布局算不算在条目内(用于noItem算法)
noItemIsHideRecyclerView(boolean)//设置是否在没有条目时隐藏RecyclerView

10.添加分割线(也可以用图片)

        //添加2px,d5d5d5的分割线
        rv.addItemDecoration_line();
        //添加d5d5d5颜色的分割线,并指定高度
        rv.addItemDecoration_line(1);
        //添加分割线,指定高度和颜色
        rv.addItemDecoration_line(1, getResources().getColor(R.color.colorAccent));
        //添加图片分割线
        rv.addItemDecoration_drawable(R.mipmap.ic_launcher);

        //设置分割线高度,可以和颜色一起设置
        app:dividerHeight="1dp"
        //设置分割线颜色
        app:dividerColor="@color/colorAccent"
        //设置图片分割线
        app:dividerDrawable="@mipmap/ic_launcher"

11.自定义上拉加载的View

11.1.通过setUpLayoutId()方法传入一个id可以控制全局的上拉刷新View

//自定义配置全局的上拉加载View       
LtRecyclerViewManager.INSTANCE.init(this)
                .setUpLayoutId(R.layout.lt_up_loading);//此方法设置一个layout的id,设置为上拉加载的View

原理是通过显示和隐藏布局内的n个View来表示刷新与否

设置该方法的布局,刷新的布局为第一个,刷新完成的布局为第二个,其他的可以通过LtAdapter.setRefresh(Int)来设置索引(从0开始)

布局伪代码示例:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout >//根布局,可以是任意ViewGroup

    <LinearLayout/>//索引0 默认是刷新时的view

    <LinearLayout/>//索引1 默认是刷新完成后的view

    //后面可以添加更多的View,通过setRefresh(Int索引)来控制显示与隐藏

</FrameLayout>

11.2.若要单独配置某一个适配器的上拉加载View

则在LtAdapter的构造里传入相应的View即可

11.3.如果不想要上拉加载,则在LtAdapter的构造里传null,默认使用全局的使用空参构造即可

12.自定义下拉刷新的View

12.1.内部有两个下拉刷新,一个是系统的SwipeRefreshLayout(已移除,如果需要可以自己自己继承SwipeRefreshLayout并实现BaseRefreshLayout接口)

和我预定义的MTextRefreshLayout

默认使用的是SwipeRefreshLayout:

可以设置为MTextRefreshLayout:

LtRecyclerViewManager.INSTANCE.init(this)
                //java8
                .setRefreshLayoutConstructorFunction(MTextRefreshLayout::new);
                //kotlin使用方式
                .setRefreshLayoutConstructorFunction(::MTextRefreshLayout)
                //java7及以下使用方式
                .setRefreshLayoutConstructorFunction(new Function3<Context, AttributeSet, Integer, BaseRefreshLayout>() {
            @Override
            public BaseRefreshLayout invoke(Context context, AttributeSet attributeSet, Integer defStyleAttr) {
                return new NewWinkChatRefreshLayout(context, attributeSet, defStyleAttr);
            }
        });

​也可以更改为rv不移动,只拉出刷新的View:

LtRecyclerViewManager.INSTANCE.init(this)
                .setRvIsMove(false)//设置下拉刷新时rv是否跟着移动,只有在自定义时可用
                .setRefreshLayoutConstructorFunction(MTextRefreshLayout::new)

12.2.也可以通过继承LtRefreshLayout来实现下拉刷新的View

示例:

public class MRefreshLayout extends LtRefreshLayout {//继承LtRefreshLayout并重写方法

    public MRefreshLayout(Context context) {
        super(context);
    }


    public MRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    public MRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    public void onStatus(int status) {
        //当状态变更时调用,在此方法中更改刷新View的状态,一共有四个状态
        public final static int STATE_REFRESH_DOWN = 0;//下拉中
        public final static int STATE_REFRESH_RELEASE = 1;//松开刷新
        public final static int STATE_REFRESHING = 2;//刷新中
        public final static int STATE_REFRESH_FINISH = 3;//刷新完成
        public final static int STATE_BACK = 4;//刷新结束,并且刷新View隐藏到了顶部
    }

    @Override
    public void onProgress(float y) {
        //当前y轴移动了多少,一般不需要这个方法,注意该方法会被频繁调用,不要在里面创建对象或耗时操作
    }

    @Override
    protected View getRefreshView() {//返回下拉刷新的View
        return null;
    }
}

LtRecyclerViewManager.INSTANCE.init(this)
                //.setRefreshThreshold(100)//设置松开刷新的位置(全局的阈值)
                .setRefreshLayoutConstructorFunction(MRefreshLayout::new);//配置全局使用自定义的刷新View

上面就完成了自定义的下拉刷新View,下拉时移动等操作已经在内部实现了,只需要控制刷新View的展示即可

而且自定义的下拉刷新View可以直接在xml文件内使用

该控件已开源,Github地址:GitHub - ltttttttttttt/ltviews: Android custom View, Contain LtRecyclerView...

若有bug可以提出来

转载请带上本文链接,谢谢

对Kotlin或KMP感兴趣的同学可以进Q群 101786950

如果这篇文章对您有帮助的话

可以扫码请我喝瓶饮料或咖啡(如果对什么比较感兴趣可以在备注里写出来)