个人博客:haichenyi.com。感谢关注
回顾
上一篇,我们讲到了Ultra-Pull-To-Refresh的基本用法。分成四步:
xml里面定义控件PtrFrameLayout
设置相关属性
添加Header,Footer,并监听
监听刷新过程
思路
目的: 做一个我们自己的自定义刷新的动画(我们先不管动画是什么,不同的需求,动画都不一样)
我们前面讲到的主要类无非就是两个: PtrFrameLayout,Header(Footer),前者是刷新控件,监听刷新过程,后者是头布局(脚布局),以添加头布局为例:我们这里首先就会想到重写这个布局。辣么?怎么重写这个头布局呢?我们先来看看怎么添加这个头布局的:
public void setHeaderView(View header) {
if (mHeaderView != null && header != null && mHeaderView != header) {
removeView(mHeaderView);
}
ViewGroup.LayoutParams lp = header.getLayoutParams();
if (lp == null) {
lp = new LayoutParams(-1, -2);
header.setLayoutParams(lp);
}
mHeaderView = header;
addView(header);
}
它这里实际上就是添加了一个View,所以,我们随便写一个自定义View,继承View就可以传进来
我们,再来看看另一个方法,就是监听的方法,这里好像也是传的View对象,因为,我们前面写的时候就是传的header:
public void addPtrUIHandler(PtrUIHandler ptrUIHandler) {
PtrUIHandlerHolder.addHandler(mPtrUIHandlerHolder, ptrUIHandler);
}
咦,不对啊,这里不是应该传的View对象么?怎么是PtrUIHandler类型的。其实,你看名字就应该看的出来,他这里传的是一个PtrUIHandler对象,点进去看,他就是一个接口。里面是下拉刷新的回调。讲到这里,我们就应该明了了,就是一个自定义View,继承View,实现PtrUIHandler接口。辣么,就开始撸了。
/**
* Author: 海晨忆
* Date: 2018/3/23
* Desc:
*/
public class MyCustomHeader extends FrameLayout implements PtrUIHandler {
public MyCustomHeader(@NonNull Context context) {
this(context, null);
}
public MyCustomHeader(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public MyCustomHeader(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
private void initView() {
LayoutInflater.from(getContext()).inflate(R.layout.header_layout, this);
}
@Override
public void onUIReset(PtrFrameLayout frame) {
}
@Override
public void onUIRefreshPrepare(PtrFrameLayout frame) {
}
@Override
public void onUIRefreshBegin(PtrFrameLayout frame) {
}
@Override
public void onUIRefreshComplete(PtrFrameLayout frame, boolean isHeader) {
}
@Override
public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status,
PtrIndicator ptrIndicator) {
}
}
可以看到,我这里面什么都没有,就是继承了FrameLayout布局,实现了PtrUIHandler接口,然后在构造方法里面加载了一个布局,添加进来,布局也很简单,里面就只有一个ImageView。布局如下:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:src="@drawable/psb17"/>
</merge>
再就是调用了,跟上一篇的调用方式一样。
final PtrFrameLayout ptrFrameLayout = findViewById(R.id.ptr_frame_layout);
MyCustomHeader myCustomHeader = new MyCustomHeader(this);
ptrFrameLayout.setHeaderView(myCustomHeader);
ptrFrameLayout.addPtrUIHandler(myCustomHeader);
ptrFrameLayout.setPtrHandler(new PtrDefaultHandler2() {
@Override
public void onRefreshBegin(PtrFrameLayout frame) {
frame.postDelayed(ptrFrameLayout::refreshComplete, 2000);
}
@Override
public void onLoadMoreBegin(PtrFrameLayout frame) {
frame.postDelayed(ptrFrameLayout::refreshComplete, 2000);
}
});
然后运行,你就会看到,刷新的header就是你的自定义view。到此,自定义刷新布局就完成了,脚布局方式类似。
什么鬼?这就没了?刷新布局就一个ImageView就没了?这么敷衍。好歹你也加个动画啊。可以可以,那就加个动画。
如你所愿,我加了一个帧动画。
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/refresh1" android:duration="100"/>
<item android:drawable="@drawable/refresh2" android:duration="100"/>
<item android:drawable="@drawable/refresh3" android:duration="100"/>
</animation-list>
header里面的改动:
private void initView() {
LayoutInflater.from(getContext()).inflate(R.layout.header_layout, this);
imageView = findViewById(R.id.img);
animationDrawable = (AnimationDrawable) imageView.getDrawable();
}
@Override
public void onUIRefreshBegin(PtrFrameLayout frame) {
imageView.setImageDrawable(animationDrawable);
animationDrawable.start();
}
@Override
public void onUIRefreshComplete(PtrFrameLayout frame, boolean isHeader) {
animationDrawable.stop();
}
在初始化的时候,把动画获取到,然后在刷新的时候开始动画,在刷新完成的时候停止动画。