package com.think.tlr;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.List;
/**
* @author borney
* @date 4/28/17
* @see android.view.View
* @see android.view.ViewGroup
*/
public class TLRLinearLayout extends ViewGroup {
private static final boolean DEBUG = false;
public static final int LABEL_HEAD = 1;
public static final int LABEL_CONTENT = 2;
public static final int LABEL_FOOT = 3;
public static final int FLAG_KEEP_CONTENT_REFRESH = 0x01;
public static final int FLAG_KEEP_CONTENT_LOAD = 0x02;
/**
* 上拉加载功能是否可用
*/
private boolean isEnableLoad = false;
/**
* 下拉刷新功能是否可用
*/
private boolean isEnableRefresh = false;
/**
* 操作过程中是否保持contentLayout不移动
*/
private int keepContentLayoutFlag = 0x00;
/**
* TLR 是否可以移动head
*/
private boolean canMoveHeadByTLR = true;
/**
* TLR 是否可以移动foot
*/
private boolean canMoveFootByTLR = true;
private View mHeaderView;
/**
* flag is {@link TLRLinearLayout#LABEL_CONTENT} view,
* 只有标记为content的view才能触发刷新或加载操作
*/
private List<View> mContentViews;
/**
* 需要向ContentLayout中添加的子view
*/
private List<View> mContentChilds;
private LinearLayout mContentLayout;
private View mFooterView;
private TLRCalculator mCalculator;
private TLRUiHandlerWrapper mUiHandlerWrapper;
private boolean isAddViewSelf = false;
private View mTouchView;
/**
* 刷新状态
*/
public enum RefreshStatus {
IDLE, PULL_DOWN, RELEASE_REFRESH, REFRESHING
}
/**
* 加载状态
*/
public enum LoadStatus {
IDLE, PULL_UP, RELEASE_LOAD, LOADING
}
public TLRLinearLayout(Context context) {
this(context, null);
}
public TLRLinearLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TLRLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs);
setWillNotDraw(false);
mUiHandlerWrapper = new TLRUiHandlerWrapper();
mCalculator = new TLRCalculator(this, attrs);
mCalculator.setTLRUiHandler(mUiHandlerWrapper);
mContentViews = new ArrayList<>();
mContentChilds = new ArrayList<>();
}
private void initAttrs(AttributeSet attrs) {
TypedArray array = getContext().obtainStyledAttributes(attrs, R.styleable.TLRLinearLayout);
if (array == null) {
TLRLog.e("initAttrs array is null");
return;
}
try {
final int N = array.getIndexCount();
for (int i = 0; i < N; i++) {
int index = array.getIndex(i);
if (index == R.styleable.TLRLinearLayout_enableLoad) {
isEnableLoad = array.getBoolean(index, false);
TLRLog.i("isEnableLoad = " + isEnableLoad);
} else if (index == R.styleable.TLRLinearLayout_enableRefresh) {
isEnableRefresh = array.getBoolean(index, false);
TLRLog.i("isEnableRefresh = " + isEnableRefresh);
} else if (index == R.styleable.TLRLinearLayout_keepContentLayout) {
keepContentLayoutFlag = array.getInt(index, keepContentLayoutFlag);
} else if (index == R.styleable.TLRLinearLayout_canMoveHeadByTLR) {
canMoveHeadByTLR = array.getBoolean(index, canMoveHeadByTLR);
TLRLog.i("canMoveHeadByTLR = " + canMoveHeadByTLR);
} else if (index == R.styleable.TLRLinearLayout_canMoveFootByTLR) {
canMoveFootByTLR = array.getBoolean(index, canMoveFootByTLR);
TLRLog.i("canMoveFootByTLR = " + canMoveFootByTLR);
}
}
} finally {
array.recycle();
}
TLRLog.i("keepContentLayoutFlag = " + keepContentLayoutFlag);
}
private void addSelfView(View child, int index, ViewGroup.LayoutParams params) {
isAddViewSelf = true;
addView(child, index, params);
isAddViewSelf = false;
}
@Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (index == 0 && !isAddViewSelf) {
TLRLog.e("can't add view index 0!!!");
return;
}
super.addView(child, index, params);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
int count = getChildCount();
mContentLayout = new LinearLayout(getContext());
mContentLayout.setOrientation(LinearLayout.VERTICAL);
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
LayoutParams params = (LayoutParams) child.getLayoutParams();
TLRLog.d("child = " + child.getClass().getSimpleName() + " params.label = "
+ params.label);
if (params.label == LABEL_HEAD) {
if (i != 0) {
throw new RuntimeException("head must in first");
}
setHeaderView(true, child);
} else if (params.label == LABEL_FOOT) {
if (i != count - 1) {
throw new RuntimeException("foot must in last!!!");
}
setFooterView(true, child);
} else if (params.label == LABEL_CONTENT) {
mContentViews.add(child);
mContentChilds.add(child);
} else {
mContentChilds.add(child);
}
}
if (mHeaderView == null) {
TLRLog.e("has not header view!!!");
if (isEnableRefresh) {
TLRLog.v("use default head view!!!");
setHeaderView(false, new TLRDefHeadView(getContext()));
}
}
if (mFooterView == null) {
TLRLog.e("has not footer view!");
if (isEnableLoad()) {
TLRLog.v("use default foot view!!!");
setFooterView(false, new TLRDefFootView(getContext()));
}
}
if (mContentChilds.size() == 0) {
throw new RuntimeException("must have content view !!!");
}
for (View view : mContentChilds) {
removeView(view);
ViewGroup.MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(params);
mContentLayout.addView(view, llp);
}
addSelfView(mContentLayout, 0,
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
TLRLog.i("ContentLayout count:" + mContentLayout.getChildCount());
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
return dispatchTouchEvent(false, ev);
}
boolean dispatchTouchEvent(boolean childIntercepted, MotionEvent ev) {
if (childIntercepted) {
return super.dispatchTouchEvent(ev);
}
if (!isEnableLoad() && !isEnableRefresh()) {
return super.dispatchTouchEvent(ev);
}
if (mCalculator.hasAnyAnimatorRunning()) {
return super.dispatchTouchEvent(ev);
}
int action = ev.getAction();
float x = ev.getX();
float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
if (!isRefreshing() && !isLoading()) {
setTouchView(x, y);
}
mCalculator.eventDown(x, y);
super.dispatchTouchEvent(ev);
return true;
case MotionEvent.ACTION_MOVE:
mCalculator.eventMove(x, y);
if (!mCalculator.isBackStatus()) {
mCalculator.touchMoveLayoutView();
return true;
}
if (mCalculator.canCalculatorV()
&& (isTouchMoveRefresh(x, y) || isTouchMoveLoad(x, y))) {
ev.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(ev);
mCalculator.touchMoveLayoutView();
return true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mCalculator.eventUp(x, y);
break;
}
return super.dispatchTouchEvent(ev);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
// Measure the child.
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
if (child.equals(mContentLayout)) {
width = child.getMeasuredWidth();
height = child.getMeasuredHeight();
} else if (child.equals(mHeaderView)) {
mCalculator.setHeadViewHeight(child.getMeasuredHeight());
} else if (child.equals(mFooterView)) {
mCalculator.setFootViewHeight(child.getMeasuredHeight());
}
if (DEBUG) {
TLRLog.d(child.getClass().getSimpleName() + " mw:" + child.getMeasuredWidth()
+ " mh:" + child.getMeasuredHeight());
}
}
}
setMeasuredDimension(width, height);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int totalOffsetY = mCalculator.getTotalOffsetY();
int parentLeft = getPaddingLeft();
int parentTop = getPaddingTop();
int parentBottom = parentTop + getMeasuredHeight();
if (mContentLayout != null && mContentLayout.getVisibility() != GONE) {
LayoutParams lp = (LayoutParams) mContentLayout.getLayoutParams();
int left = parentLeft + lp.leftMargin;
int top = parentTop + lp.topMargin;
if (mCalculator.getTotalOffsetY() > 0 && (keepContentLayoutFlag & FLAG_KEEP_CONTENT_REFRESH) == 0) {
top += totalOffsetY;
} else if (mCalculator.getTotalOffsetY() < 0 && (keepContentLayoutFlag & FLAG_KEEP_CONTENT_LOAD) == 0) {
top += totalOffsetY;
}
int right = left + mContentLayout.getMeasuredWidth();
int bottom = top + mContentLayout.getMeasuredHeight();
if (DEBUG) {
TLRLog.i("ContentLayout left:" + left + " right:" + right + " top:" + top
+ " bottom:" + bottom);
}
mContentLayout.layout(left, top, right, bottom);
}
if (mHeaderView != null && mHeaderView.getVisibility() != GONE) {
LayoutParams lp = (LayoutParams) mHeaderView.getLayoutParams();
int left = parentLeft + lp.leftMargin;
int bottom = parentTop - lp.bottomMargin;//layout head calculator bottom first
if (isEnableRefresh && canMoveHeadByTLR) { //refresh is enabled
bottom += totalOffsetY;
}
int right = left + mHeaderView.getMeasuredWidth();
int top = bottom - mHeaderView.getMeasuredHeight();
if (DEBUG) {
TLRLog.i("HeaderView left:" + left + " right:" + right + " top:" + top + " bottom:"
+ bottom);
}
mHeaderView.layout(left, top, right, bottom);
}
if (mFooterView != null && mFooterView.getVisibility() != GONE) {
LayoutParams lp = (LayoutParams) mFooterView.getLayoutParams();
int left = parentLeft + lp.leftMargin;
int top = parentBottom + lp.topMargin;//layout foot calculator top first
if (isEnableLoad && canMoveFootByTLR) { //load is enabled
top += totalOffsetY;
}
int right = left + mFooterView.getMeasuredWidth();
int bottom = top + mFooterView.getMeasuredHeight();
if (DEBUG) {
TLRLog.i("FooterView left:" + left + " right:" + right + " top:" + top + " bottom:"
+ bottom);
}
mFooterView.layout(left, top, right, bottom);
}
}
void move(int y) {
if (isEnableRefresh() && isCanMoveHeadByTLR() && mHeaderView != null) {
mHeaderView.offsetTopAndBottom(y);
}
if (isEnableLoad() && isCanMoveFootByTLR() && mFooterView != null) {
mFooterView.offsetTopAndBottom(y);
}
if (mCalculator.getTotalOffsetY() > 0 && (keepContentLayoutFlag & FLAG_KEEP_CONTENT_REFRESH) == 0) {
mContentLayout.offsetTopAndBottom(y);
} else if (mCalculator.getTotalOffsetY() < 0 && (keepContentLayoutFlag & FLAG_KEEP_CONTENT_LOAD) == 0) {
mContentLayout.offsetTopAndBottom(y);
}
}
/**
* call by child
*/
TLRCalculator calculator() {
return mCalculator;
}
private void setTouchView(float downx, float downy) {
for (View view : mContentViews) {
if (inView(view, downx, downy)) {
setTouchView(view);
break;
}
}
}
void setTouchView(View touchView) {
if (mTouchView != touchView) {
mTouchView = touchView;
}
}
View getTouchView() {
return mTouchView;
}
private boolean isTouchMoveRefresh(float x, float y) {
boolean refresh = false;
for (View view : mContentViews) {
if (isTouchViewRefresh(view, x, y)) {
refresh = true;
break;
}
}
refresh &= isEnableRefresh();
if (DEBUG) {
TLRLog.i("isTouchMoveRefresh refresh:" + refresh);
}
return refresh;
}
private boolean isTouchMoveLoad(float x, float y) {
boolean load = false;
for (View view : mContentViews) {
if (isTouchViewLoad(view, x, y)) {
load = true;
break;
}
}
load &= isEnableLoad();
if (DEBUG) {
TLRLog.i("isTouchMoveLoad load:" + load);
}
return load;
}
private boolean inView(View view, float x, float y) {
final int scrollY = getScrollY();
return !(y < view.getTop() - scrollY
|| y >= view.getBottom() - scrollY
|| x < view.getLeft()
|| x >= view.getRight());
}
private boolean isTouchViewRefresh(View target, float x, float y) {
boolean inView = inView(target, x, y);
if (inView && mCalculator.getDirection() == TLRCalculator.Direction.DOWN) {
return isViewRefresh(target);
}
return false;
}
private boolean isTouchViewLoad(View target, float x, float y) {
boolean inView = inView(target, x, y);
if (inView && mCalculator.getDirection() == TLRCalculator.Direction.UP) {
return isViewLoad(target);
}
return false;
}
private boolean isViewRefresh(View target) {
return !ViewCompat.canScrollVertically(target, -1);
}
private boolean isViewLoad(View target) {
return !ViewCompat.canScrollVertically(target, 1);
}
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(getContext());
}
@Override
public LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
return generateDefaultLayoutParams();
}
/**
* start auto refresh
*/
public void autoRefresh() {
mCalculator.startAutoRefresh();
}
/**
* finish refresh success or not
*/
public void finishRefresh(boolean isSuccess) {
finishRefresh(isSuccess, -1);
}
/**
* finish refresh success or not, cotain errorCode
*/
public void finishRefresh(boolean isSuccess, int errorCode) {
mCalculator.finishRefresh(isSuccess, errorCode);
}
/**
* finish load success or not
*/
public void finishLoad(boolean isSuccess) {
finishLoad(isSuccess, -1);
}
/**
* finish load success or not, cotain errorCode
*/
public void finishLoad(boolean isSuccess, int errorCode) {
mCalculator.finishLoad(isSuccess, errorCode);
}
/**
* add {@link TLRUIHandler} callback
*/
public void addTLRUiHandler(TLRUIHandler handler) {
mUiHandlerWrapper.addTLRUiHandler(handler);
}
/**
* remove {@link TLRUIHandler} callback
*/
public void removeTLRUiHandler(TLRUIHandler handler) {
mUiHandlerWrapper.removeTLRUiHandler(handler);
}
/**
* add hook when ui ready to reset
*/
public void hook(TLRUIHandlerHook hook) {
mCalculator.hook(hook);
}
/**
* remove hook, must call if you set hook
*/
public void releaseHook(TLRUIHandlerHook hook) {
mCalculator.releaseHook(hook);
}
/**
* return load is enable or not
*/
public boolean isEnableLoad() {
return isEnableLoad;
}
/**
* set load is enable or not
*/
public void setEnableLoad(boolean enableLoad) {
isEnableLoad = enableLoad;
}
/**
* return refresh is enable or not
*/
public boolean isEnableRefresh() {
return isEnableRefresh;
}
/**
* set refresh is enable or not
*/
public void setEnableRefresh(boolean enableRefresh) {
isEnableRefresh = enableRefresh;
}
/**
* return contentLayout can not move on refresh or load
*/
public int keepContentLayoutFlag() {
return keepContentLayoutFlag;
}
/**
* get {@link TLRLinearLayout} can move head view
*/
public boolean isCanMoveHeadByTLR() {
return canMoveHeadByTLR;
}
/**
* get {@link TLRLinearLayout} can move foot view
*/
public boolean isCanMoveFootByTLR() {
return canMoveFootByTLR;
}
/**
* get head view
*/
public View getHeaderView() {
return mHeaderView;
}
/**
* set head view
*/
public void setHeaderView(View headerView) {
setHeaderView(false, headerView);
}
private void setHeaderView(boolean isAdded, View headerView) {
if (headerView == null || mHeaderView == headerView) {
return;
}
if (isAdded) {
mHeaderView = headerView;
} else {
mHeaderView = headerView;
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.label = LABEL_HEAD;
addView(mHeaderView, params);
}
TLRLog.d("setHeaderView:" + mHeaderView.getClass().getSimpleName());
if (mHeaderView instanceof TLRUIHandler) {
addTLRUiHandler((TLRUIHandler) mHeaderView);
}
}
/**
* set foot view
*/
public void setFooterView(View footerView) {
setFooterView(false, footerView);
}
private void setFooterView(boolean isAdded, View footerView) {
if (footerView == null || mFooterView == footerView) {
return;
}
if (isAdded) {
mFooterView = footerView;
} else {
mFooterView = footerView;
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.label = LABEL_FOOT;
addView(mFooterView, params);
}
TLRLog.d("setFooterView:" + mFooterView.getClass().getSimpleName());
if (mFooterView instanceof TLRUIHandler) {
addTLRUiHandler((TLRUIHandler) mFooterView);
}
}
/**
* get foot view
*/
public View getFooterView() {
return mFooterView;
}
/**
* get the refresh factor
*/
public float getRefreshThreshold() {
return mCalculator.getRefreshThreshold();
}
/**
* Set the refresh factor
*/
public void setRefreshThreshold(float refreshThreshold) {
mCalculator.setRefreshThreshold(refreshThreshold);
}
/**
* get the load factor
*/
public float getLoadThreshold() {
return mCalculator.getLoadThreshold();
}
/**
* Set the load factor
*/
public void setLoadThreshold(float loadThreshold) {
mCalculator.setLoadThreshold(loadThreshold);
}
/**
* get the maximum travel distance to refresh
*/
public int getRefreshMaxMoveDistance() {
return mCalculator.getRefreshMaxMoveDistance();
}
/**
* Set the maximum travel distance to refresh
*/
public void setRefreshMaxMoveDistance(int refreshMaxMoveDistance) {
mCalculator.setRefreshMaxMoveDistance(refreshMaxMoveDistance);
}
/**
* get the maximum travel distance to load
*/
public int getLoadMaxMoveDistance() {
return mCalculator.getLoadMaxMoveDistance();
}
/**
* Set the maximum travel distance to load
*/
public void setLoadMaxMoveDistance(int loadMaxMoveDistance) {
mCalculator.setLoadMaxMoveDistance(loadMaxMoveDistance);
}
/**
* get the damping coefficient
*/
public float getResistance() {
return mCalculator.getResistance();
}
/**
* set the damping coefficient
*/
public void setResistance(float resistance) {
mCalculator.setResistance(resistance);
}
/**
* Set the reset the animation duration
*/
public void setCloseAnimDuration(int closeAnimDuration) {
mCalculator.setCloseAnimDuration(closeAnimDuration);
}
/**
* Set the auto refresh to open the animation duration
*/
public void setOpenAnimDuration(int openAnimDuration) {
mCalculator.setOpenAnimDuration(openAnimDuration);
}
/**
* return keep head view when refreshing
*/
public boolean isKeepHeadRefreshing() {
return mCalculator.isKeepHeadRefreshing();
}
/**
* When refresh, whether or not to stay head view
*/
public void setKeepHeadRefreshing(boolean keepHeadRefreshing) {
mCalculator.setKeepHeadRefreshing(keepHeadRefreshing);
}
/**
* return keep foot view when loading
*/
public boolean isKeepFootLoading() {
return mCalculator.isKeepFootLoading();
}
/**
* When loaded, whether to stay foot view
*/
public void setKeepFootLoading(boolean keepFootLoading) {
mCalculator.setKeepFootLoading(keepFootLoading);
}
/**
* Whether to release the refresh
*/
public boolean isReleaseRefresh() {
return mCalculator.isReleaseRefresh();
}
/**
* set whether to release the refresh
*/
public void setReleaseRefresh(boolean releaseRefresh) {
mCalculator.setReleaseRefresh(releaseRefresh);
}
/**
* Whether to release the load
*/
public boolean isReleaseLoad() {
return mCalculator.isReleaseLoad();
}
/**
* set whether to release the load
*/
public void setReleaseLoad(boolean releaseLoad) {
mCalculator.setReleaseLoad(releaseLoad);
}
/**
* return has any animation is running
*/
public boolean hasAnyAnimatorRunning() {
return mCalculator.hasAnyAnimatorRunning();
}
/**
* Returns whether it is refreshing
*/
public boolean isRefreshing() {
return mCalculator.isRefreshing();
}
/**
* Returns whether it is loading
*/
public boolean isLoading() {
return mCalculator.isLoading();
}
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
int label = 0;
public LayoutParams(Context c) {
this(c, null);
}
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray array = c.obtainStyledAttributes(attrs, R.styleable.TLRLinearLayout_Layout);
try {
final int N = array.getIndexCount();
for (int i = 0; i < N; i++) {
int index = array.getIndex(i);
if (index == R.styleable.TLRLinearLayout_Layout_label) {
label = array.getInt(R.styleable.TLRLinearLayout_Layout_label, 0);
}
}
} finally {
array.recycle();
}
}
public LayoutParams(int width, int height) {
super(width, height);
}
public int getLabel() {
return label;
}
}
private static class TLRUiHandlerWrapper implements TLRUIHandler {
private final List<TLRUIHandler> mTLRUiHandlers = new ArrayList<>();
public void addTLRUiHandler(TLRUIHandler handler) {
if (handler != null) {
mTLRUiHandlers.add(handler);
}
}
public void removeTLRUiHandler(TLRUIHandler handler) {
if (handler != null) {
for (TLRUIHandler uiHandler : mTLRUiHandlers) {
if (uiHandler.equals(handler)) {
mTLRUiHandlers.remove(uiHandler);
break;
}
}
}
}
@Override
public void onRefreshStatusChanged(View target, RefreshStatus status) {
if (DEBUG) {
String name = target == null ? null : target.getClass().getSimpleName();
TLRLog.d("onRefreshStatusChanged target:" + name + " status:" + status + " size:"
+ mTLRUiHandlers.size());
}
for (TLRUIHandler handler : mTLRUiHandlers) {
handler.onRefreshStatusChanged(target, status);
}
}
@Override
public void onLoadStatusChanged(View target, LoadStatus status) {
if (DEBUG) {
String name = target == null ? null : target.getClass().getSimpleName();
TLRLog.i("onLoadStatusChanged target:" + name + " status:" + status + " size:"
+ mTLRUiHandlers.size());
}
for (TLRUIHandler handler : mTLRUiHandlers) {
handler.onLoadStatusChanged(target, status);
}
}
@Override
public void onOffsetChanged(View target, boolean isRefresh, int totalOffsetY,
int totalThresholdY, int offsetY, float threshOffset) {
if (DEBUG) {
String name = target == null ? null : target.getClass().getSimpleName();
TLRLog.v("onOffsetChanged target:" + name + " isRefresh:" + isRefresh
+ " totalOffsetY:" + totalOffsetY + " totalThresholdY:" + totalThresholdY
+ " offsetY:" + offsetY + " threshOffset:" + threshOffset);
}
for (TLRUIHandler handler : mTLRUiHandlers) {
handler.onOffsetChanged(target, isRefresh, totalOffsetY, totalThresholdY, offsetY,
threshOffset);
}
}
@Override
public void onFinish(View target, boolean isRefresh, boolean isSuccess, int errorCode) {
if (DEBUG) {
String name = target == null ? null : target.getClass().getSimpleName();
TLRLog.i("onFinish target:" + name + " isRefresh:" + isRefresh + " isSuccess:"
+ isSuccess + " errorCode:" + errorCode);
}
for (TLRUIHandler handler : mTLRUiHandlers) {
handler.onFinish(target, isRefresh, isSuccess, errorCode);
}
}
}
}