Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

转载自这个控件的git hub地址:https://github.com/xubinhong/PullToRefreshLayout


如果你需要在3分钟之内集成一个下拉刷新控件并且把他的UI随心所欲的定制,那么你来对地方了。


先上效果图

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一


*定制:

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

也就是说,这一块你是可以随便放什么的,精美的UI可以由你自己来打造。

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

此外,这个箭头的旋转你也可以自己打造,因为我开放出了对应的回调,在你下拉到一定高度后,这个回调会被调用,你可以在里面做比如,旋转这个箭头的操作,设置文字的操作,等等。这就是这个控件的高度灵活之处。

它的优点也是他的缺点,由于你可以随心所欲定制UI,所以你可能需要多写一点点代码。UI变换的代码需要自己写,不像其他下拉刷新控件一样,他固定了你的UI样式。


不过,虽然你需要写UI变换的代码,不过你所需要做的,也仅仅是UI变换的代码了。

refreshLayout.setListener(new PullToRefreshLayout.Listener() {
    @Override
    public void onChange() {
        
    }

    @Override
    public void onRecover() {

    }

    @Override
    public void onRefresh() {

    }

    @Override
    public void onFinish() {

    }
});

这里有4个回调,是非常好理解的4个回调。

onChange,当你下拉到一定高度,这个高度,超过了header的高度后,会执行这个回调。对应图中也就是,旋转箭头,修改文字从“下拉刷新”到“释放刷新”

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

onRecover,也就是低于这个header高度后的一个恢复操作了。对应图中也就是,把箭头转回去,修改文字从“释放刷新”到“ 下拉刷新”

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

onRefresh,也就是你超过header的时候,手松开,会进行一个刷新。这里用来书写你的网络请求。UI的话,对应图中就是,把箭头隐藏,显示progress dialog。并且把文字修改成刷新中。

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

onFinish,也就是你网络请求完成后,需要把刷新中的UI,修改回我们一开始的UI。所以你需要在网络请求成功后,手动调用

refreshFinished方法来进行一个结束。这里用按钮,模拟网络请求结束,还请见谅。


下面我们从整体来看看怎么使用这个控件,你会发现,实在太简单了


header xml

<?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="60dp"
    android:gravity="center"
    android:background="#CCCCCC">

    <ImageView
        android:id="@+id/iv"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:background="@drawable/arrow_bottom" />

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:visibility="gone"
        />

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:text="下拉刷新" />

</LinearLayout>

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一


主界面中

<com.example.demo.PullToRefreshLayout
    android:id="@+id/refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</com.example.demo.PullToRefreshLayout>

我们仿照官方下拉刷新控件的思路,解决了很大一部分耦合


初始化我们的header view(这里的setHeader就是帮你省去了LayoutInflater的代码)

//header

View header = refreshLayout.setHeader(R.layout.header);

TextView tv = header.findViewById(R.id.tv);
ImageView iv = header.findViewById(R.id.iv);
ProgressBar progressBar = header.findViewById(R.id.progress_bar);


回调进行对UI的操作


refreshLayout.setListener(new PullToRefreshLayout.Listener() {
    @Override
    public void onChange() {
        tv.setText("释放刷新");
        
        //旋转箭头
        
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "rotation", 0f, -180f);
        objectAnimator.setDuration(500);
        objectAnimator.start();
    }

    @Override
    public void onRecover() {
        tv.setText("下拉刷新");
        
        //把箭头转回来
        
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "rotation", -180f, 0);
        objectAnimator.setDuration(500);
        objectAnimator.start();
    }

    @Override
    public void onRefresh() {
        tv.setText("刷新中");

        //复原ImageView的朝向成初始状态(被属性动画改变了)
        
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(iv, "rotation", -180f, 0);
        objectAnimator.setDuration(0);
        objectAnimator.start();
        
        //隐藏ImageView,显示圆形进度条控件

        iv.setVisibility(View.GONE);
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void onFinish() {
        tv.setText("下拉刷新");
        
        //隐藏圆形进度条,显示ImageView

        iv.setVisibility(View.VISIBLE);
        progressBar.setVisibility(View.GONE);
    }
});


至此全部搞定,真的是非常的简单易用,我们所做的无非就是:

1.写一个header view

2.在xml中把recycler view放到我们的pull to refresh layout里

3.写回调,对UI操作


编写思路:

其实写一个下拉刷新实在是很简单,只需要在onInterceptTouchEvent里面,判断好进入下拉刷新状态的逻辑,然后进行拦截,后面都会默认拦截了。


如果想学习如何制作:https://blog.csdn.net/qq_36523667/article/details/79263644

如果想看源码和demo:https://github.com/xubinhong/PullToRefreshLayout


----------更新-----------

Android自己写一个高度定制化UI的下拉刷新控件,使用十分简单方便,GitHub最火的开源控件之一

对于这种,随着下拉的距离延长,同样有一些动画的情况,需要在原有的4个接口上再多开放一个接口onPull。即下拉的距离占header高度的百分比

public interface Listener {
    void onChange();//下拉刷新->释放刷新
    void onRecover();//释放刷新->下拉刷新

    void onRefresh();//释放刷新->刷新中
    void onFinish();//刷新中->下拉刷新
    
    void onPull(float rate);
}

已在github上更新