非常简单的自定义SmartRefreshLayout上拉加载下拉刷新的头部和尾部

自定义SmartRefreshLayout上拉加载下拉刷新的头部和尾部

引入依赖

在app的build.gradle 引入

implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0'
implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0'//没有使用特殊Header,可以不加这行
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'

还需要在本文件加入

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

自定义头部尾部

由于smartRefreshLayout 自带的头部尾部一般不适合应用于自己的项目中,那么我们就需要自定义头部尾部View。

自定义头部View

/**
 * Created by yangyang on 2022/10/14.
 */
public class MyRefreshHeader extends LinearLayout implements RefreshHeader {

    private final ImageView ivHeader;
    private final TextView headText;
    private Animation mAnimRefresh;

    /**
     * 1,构造方法
     */
    public MyRefreshHeader(Context context) {
        this(context, null, 0);
    }

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

    public MyRefreshHeader(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        View view = View.inflate(context, R.layout.refresh_header_view, this);
        ivHeader = view.findViewById(R.id.iv_refresh_header);
        headText = view.findViewById(R.id.tv_header);
    }

    /**
     * 2,获取真实视图(必须返回,不能为null)一般就是返回当前自定义的view
     */
    @NonNull
    @Override
    public View getView() {
        return this;
    }

    /**
     * 3,获取变换方式(必须指定一个:平移、拉伸、固定、全屏),Translate指平移,大多数都是平移
     */
    @NonNull
    @Override
    public SpinnerStyle getSpinnerStyle() {
        return SpinnerStyle.Translate;
    }

    /**
     * 4,一般可以理解为一下case中的三种状态,在达到相应状态时候开始改变
     * 注意:这三种状态都是初始化的状态
     */
    @Override
    public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
        switch (newState) {
            case None:
            case PullDownToRefresh:
                ivHeader.setImageResource(R.mipmap.ic_launcher);
                headText.setText("下拉开始刷新");
                break;
            case Refreshing:
                headText.setText("正在刷新...");
                ivHeader.setImageResource(R.mipmap.ic_launcher);
                mAnimRefresh = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                mAnimRefresh.setFillAfter(!mAnimRefresh.getFillAfter());
                mAnimRefresh.setDuration(500);
                mAnimRefresh.setRepeatCount(Animation.INFINITE);
                ivHeader.startAnimation(mAnimRefresh);
                break;
            case ReleaseToRefresh:
                headText.setText("释放立即刷新");
                ivHeader.setImageResource(R.mipmap.ic_launcher);
                break;
            default:
        }
    }

    /**
     * 5,结束下拉刷新的时候需要关闭动画
     *
     * @param refreshLayout
     * @param success
     * @return
     */
    @Override
    public int onFinish(@NonNull RefreshLayout refreshLayout, boolean success) {
        if (mAnimRefresh != null && mAnimRefresh.hasStarted()) {
            mAnimRefresh.cancel();
        }
        if (success) {
            headText.setText("刷新完成");
        } else {
            headText.setText("刷新失败");
        }
        return 200;
    }

    @Override
    public void onStartAnimator(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {

    }

    @Override
    public void setPrimaryColors(int... colors) {

    }

    @Override
    public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {

    }

    @Override
    public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {

    }

    @Override
    public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {

    }

    @Override
    public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {

    }

    @Override
    public boolean isSupportHorizontalDrag() {
        return false;
    }

}

refresh_header_view 布局文件

这里的动画效果可以根据自己项目的实际需要来修改,上面代码是图片旋转360度。这里也可以用Glide加载动态图,这个看自己的喜好,实现方式有很多种。(附效果图用的是Glide加载的动图)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="@color/white"
    android:orientation="vertical"
    android:padding="5dp"
    android:gravity="center"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/iv_refresh_header"
        android:translationY="0dp"
        android:layout_height="40dp"
        android:layout_width="40dp"/>
    <TextView
        android:id="@+id/tv_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"/>
</LinearLayout>

自定义尾部View

public class MyRefreshFooter extends LinearLayout implements RefreshFooter {

    private final TextView tvFooter;
    private final ProgressBar progressBar;

    public MyRefreshFooter(Context context) {
        this(context, null, 0);
    }

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

    public MyRefreshFooter(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        View view = View.inflate(context, R.layout.refresh_footer_view, this);
        tvFooter = view.findViewById(R.id.tv_footer);
        progressBar = view.findViewById(R.id.progressBar);

    }


    @NonNull
    @Override
    public View getView() {
        return this;
    }

    @NonNull
    @Override
    public SpinnerStyle getSpinnerStyle() {
        return SpinnerStyle.Translate;
    }

    @Override
    public void setPrimaryColors(int... colors) {

    }

    @Override
    public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {
    }

    @Override
    public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {

    }

    @Override
    public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {

    }

    @Override
    public void onStartAnimator(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) {
    }

    @Override
    public int onFinish(@NonNull RefreshLayout refreshLayout, boolean success) {
        progressBar.setVisibility(View.GONE);
        if (success) {
            tvFooter.setText("加载完成");
        } else {
            tvFooter.setText("加载失败");
        }
        return 200;
    }

    @Override
    public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {

    }

    @Override
    public boolean isSupportHorizontalDrag() {
        return false;
    }

    @Override
    public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
        switch (newState) {
            case None:
            case Loading:
                progressBar.setVisibility(View.VISIBLE);
                tvFooter.setText("正在加载");
                break;
            case PullUpToLoad:
                progressBar.setVisibility(View.GONE);
                tvFooter.setText("已全部加载完毕");
                break;
        }
    }

    @Override
    public boolean setNoMoreData(boolean noMoreData) {
        return false;
    }
}

跟头部很类似,动画效果可以按自己项目需求修改,我的是文字后面加了ProgressBar。

refresh_footer_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="30dp"
    android:gravity="center"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/tv_footer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/transparent"
        android:indeterminateBehavior="repeat"
        android:indeterminateDrawable="@drawable/progressbar_style"
        android:indeterminateDuration="2" />

</LinearLayout>

progressbar_style 文件代码

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="360">
    <shape
        android:innerRadius="8dp"
        android:thickness="3dp"
        android:shape="ring"
        android:useLevel="false">
        <gradient
            android:centerY="0.50"
            android:endColor="#cccccc"
            android:startColor="@color/white"
            android:type="sweep"
            android:useLevel="false" />
    </shape>
</animated-rotate>

至此一个简单好用的SmartRefreshLayout的头部尾部就好了。

使用

public class SmartRefreshLayoutActivity extends BaseActivity {
    SmartRefreshLayout smartRefreshLayout;
    RecyclerView recyclerView;
    MyAdapter adapter;
    List<String> dataList = new ArrayList<>();


    @Override
    protected int initLayout() {
        return R.layout.activity_smart_refresh;
    }

    @Override
    protected void initView() {
        setTitle("SmartRefreshLayout自定义头尾部");
        finishActivity();
        smartRefreshLayout = findViewById(R.id.smartLayout);
        smartRefreshLayout.setRefreshHeader(new MyRefreshHeader(this));
        smartRefreshLayout.setRefreshFooter(new MyRefreshFooter(this));
        recyclerView = findViewById(R.id.recycleView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new MyAdapter(dataList);
        recyclerView.setAdapter(adapter);
        setData();
    }

    @Override
    protected void initData() {
        smartRefreshLayout.setOnLoadMoreListener(refreshlayout -> {
            new Handler().postDelayed(() -> {
                setData();
                refreshlayout.finishLoadMoreWithNoMoreData();
            }, 500);
        });
        smartRefreshLayout.setOnRefreshListener(refreshlayout -> {
            new Handler().postDelayed(() -> {
                dataList.clear();
                setData();
                refreshlayout.finishRefresh(); // TODO
            }, 500);
        });
    }

    private void setData() {
        dataList.add("1");
        dataList.add("2");
        dataList.add("3");
        dataList.add("4");
        dataList.add("5");
        dataList.add("6");
        adapter.setNewData(dataList);
    }
}

布局文件activity_smart_refresh


<?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="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical">
    <include
        android:id="@+id/lin"
        layout="@layout/base_title" />

    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:id="@+id/smartLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycleView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:itemCount="3"/>

    </com.scwang.smartrefresh.layout.SmartRefreshLayout>

</LinearLayout>

MyAdapter代码

public class MyAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
    private List<String> datas=new ArrayList<>();
    public MyAdapter(@Nullable List<String> data) {
        super(R.layout.list_item, data);
    }
    @Override
    protected void convert(@NonNull BaseViewHolder helper, String item) {
        helper.setText(R.id.tv,item);
    }
}

布局文件list_item

<?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="40dp"
    android:layout_margin="10dp"
    android:background="#00FFFF"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="1"
        android:textColor="#ffffff"
        android:textSize="16sp" />


</LinearLayout>

附效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值