package com.lcodecore.tkrefreshlayout.processor;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
import com.lcodecore.tkrefreshlayout.utils.ScrollingUtil;
/**
* Created by lcodecore on 2017/3/1.
*/
public class RefreshProcessor implements IDecorator {
protected TwinklingRefreshLayout.CoContext cp;
public RefreshProcessor(TwinklingRefreshLayout.CoContext processor) {
if (processor == null) throw new NullPointerException("The coprocessor can not be null.");
cp = processor;
}
private float mTouchX, mTouchY;
private boolean intercepted = false;
private boolean willAnimHead = false;
private boolean willAnimBottom = false;
private boolean downEventSent = false;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downEventSent = false;
intercepted = false;
mTouchX = ev.getX();
mTouchY = ev.getY();
if (cp.isEnableKeepIView()) {
if (!cp.isRefreshing()) {
cp.setPrepareFinishRefresh(false);
}
if (!cp.isLoadingMore()) {
cp.setPrepareFinishLoadMore(false);
}
}
cp.dispatchTouchEventSuper(ev);
return true;
case MotionEvent.ACTION_MOVE:
mLastMoveEvent = ev;
float dx = ev.getX() - mTouchX;
float dy = ev.getY() - mTouchY;
if (!intercepted && Math.abs(dx) <= Math.abs(dy) && Math.abs(dy) > cp.getTouchSlop()) {//滑动允许最大角度为45度
if (dy > 0 && ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop()) && cp.allowPullDown()) {
cp.setStatePTD();
mTouchX = ev.getX();
mTouchY = ev.getY();
sendCancelEvent();
intercepted = true;
return true;
} else if (dy < 0 && ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop()) && cp.allowPullUp()) {
cp.setStatePBU();
mTouchX = ev.getX();
mTouchY = ev.getY();
intercepted = true;
sendCancelEvent();
return true;
}
}
if (intercepted) {
if (cp.isRefreshVisible() || cp.isLoadingVisible()) {
return cp.dispatchTouchEventSuper(ev);
}
if (!cp.isPrepareFinishRefresh() && cp.isStatePTD()) {
if (dy < -cp.getTouchSlop() || !ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop())) {
cp.dispatchTouchEventSuper(ev);
}
dy = Math.min(cp.getMaxHeadHeight() * 2, dy);
dy = Math.max(0, dy);
cp.getAnimProcessor().scrollHeadByMove(dy);
} else if (!cp.isPrepareFinishLoadMore() && cp.isStatePBU()) {
//加载更多的动作
if (dy > cp.getTouchSlop() || !ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop())) {
cp.dispatchTouchEventSuper(ev);
}
dy = Math.max(-cp.getMaxBottomHeight() * 2, dy);
dy = Math.min(0, dy);
cp.getAnimProcessor().scrollBottomByMove(Math.abs(dy));
}
if (dy == 0 && !downEventSent) {
downEventSent = true;
sendDownEvent();
}
return true;
}
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (intercepted) {
if (cp.isStatePTD()) {
willAnimHead = true;
} else if (cp.isStatePBU()) {
willAnimBottom = true;
}
intercepted = false;
return true;
}
break;
}
return cp.dispatchTouchEventSuper(ev);
}
private MotionEvent mLastMoveEvent;
//发送cancel事件解决selection问题
private void sendCancelEvent() {
if (mLastMoveEvent == null) {
return;
}
MotionEvent last = mLastMoveEvent;
MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime() + ViewConfiguration.getLongPressTimeout(), MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), last.getMetaState());
cp.dispatchTouchEventSuper(e);
}
private void sendDownEvent() {
final MotionEvent last = mLastMoveEvent;
MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState());
cp.dispatchTouchEventSuper(e);
}
@Override
public boolean interceptTouchEvent(MotionEvent ev) {
return false;
}
@Override
public boolean dealTouchEvent(MotionEvent e) {
return false;
}
@Override
public void onFingerDown(MotionEvent ev) {
}
@Override
public void onFingerUp(MotionEvent ev, boolean isFling) {
if (!isFling && willAnimHead) {
cp.getAnimProcessor().dealPullDownRelease();
}
if (!isFling && willAnimBottom) {
cp.getAnimProcessor().dealPullUpRelease();
}
willAnimHead = false;
willAnimBottom = false;
}
@Override
public void onFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY, float velocityX, float velocityY) {
//手指在屏幕上滚动,如果此时正处在刷新状态,可隐藏
int mTouchSlop = cp.getTouchSlop();
if (cp.isRefreshVisible() && distanceY >= mTouchSlop && !cp.isOpenFloatRefresh()) {
cp.getAnimProcessor().animHeadHideByVy((int) velocityY);
}
if (cp.isLoadingVisible() && distanceY <= -mTouchSlop) {
cp.getAnimProcessor().animBottomHideByVy((int) velocityY);
}
}
@Override
public void onFingerFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
}
}