转载自这个控件的git hub地址:https://github.com/xubinhong/PullToRefreshLayout
如果你需要在3分钟之内集成一个下拉刷新控件并且把他的UI随心所欲的定制,那么你来对地方了。
先上效果图
自由定制:
也就是说,这一块你是可以随便放什么的,精美的UI可以由你自己来打造。
此外,这个箭头的旋转你也可以自己打造,因为我开放出了对应的回调,在你下拉到一定高度后,这个回调会被调用,你可以在里面做比如,旋转这个箭头的操作,设置文字的操作,等等。这就是这个控件的高度灵活之处。
它的优点也是他的缺点,由于你可以随心所欲定制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的高度后,会执行这个回调。对应图中也就是,旋转箭头,修改文字从“下拉刷新”到“释放刷新”
onRecover,也就是低于这个header高度后的一个恢复操作了。对应图中也就是,把箭头转回去,修改文字从“释放刷新”到“ 下拉刷新”
onRefresh,也就是你超过header的时候,手松开,会进行一个刷新。这里用来书写你的网络请求。UI的话,对应图中就是,把箭头隐藏,显示progress dialog。并且把文字修改成刷新中。
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>
主界面中
<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
----------更新-----------
对于这种,随着下拉的距离延长,同样有一些动画的情况,需要在原有的4个接口上再多开放一个接口onPull。即下拉的距离占header高度的百分比
public interface Listener { void onChange();//下拉刷新->释放刷新 void onRecover();//释放刷新->下拉刷新 void onRefresh();//释放刷新->刷新中 void onFinish();//刷新中->下拉刷新 void onPull(float rate); }
已在github上更新