/**
* A ScrollView which can scroll to (0,0) when pull down or up.
* 能够上下拖拽的ScrollView ,
* 视差比例 0.5
*/
public class StretchScrollView extends ScrollView {
private static final String TAG =
"StretchScrollView";
private static final float MOVE_FACTOR =
0.5f;
private static final int ANIM_TIME =
300;
private View contentView;
private float startY;
private Rect originalRect =
new Rect();
private boolean canPullDown =
false;
private boolean canPullUp =
false;
private boolean isMoved =
false;
public StretchScrollView(Context context) {
super(context);
}
public StretchScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
if (getChildCount() >
0) {
contentView = getChildAt(
0);
}
}
@Override
protected void onLayout(
boolean changed,
int l,
int t,
int r,
int b) {
super.onLayout(changed, l, t, r, b);
if (contentView ==
null)
return;
originalRect.set(contentView.getLeft(), contentView.getTop(), contentView
.getRight(), contentView.getBottom());
}
/**
* 在触摸事件中, 处理上拉和下拉的逻辑
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (contentView ==
null) {
return super.dispatchTouchEvent(ev);
}
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
canPullDown = isCanPullDown();
canPullUp = isCanPullUp();
startY = ev.getY();
break;
case MotionEvent.ACTION_UP:
if (!isMoved)
break;
TranslateAnimation anim =
new TranslateAnimation(
0,
0, contentView.getTop(),
originalRect.top);
anim.setDuration(ANIM_TIME);
anim.setInterpolator(
new AccelerateDecelerateInterpolator());
contentView.startAnimation(anim);
contentView.layout(originalRect.left, originalRect.top,
originalRect.right, originalRect.bottom);
canPullDown =
false;
canPullUp =
false;
isMoved =
false;
break;
case MotionEvent.ACTION_MOVE:
if (!canPullDown && !canPullUp) {
startY = ev.getY();
canPullDown = isCanPullDown();
canPullUp = isCanPullUp();
break;
}
float nowY = ev.getY();
int deltaY = (
int) (nowY - startY);
boolean shouldMove =
(canPullDown && deltaY >
0)
|| (canPullUp && deltaY <
0)
|| (canPullUp && canPullDown);
if (shouldMove) {
int offset = (
int) (deltaY * MOVE_FACTOR);
contentView.layout(originalRect.left, originalRect.top + offset,
originalRect.right, originalRect.bottom + offset);
if (listener !=
null) {
listener.onScroll(offset);
}
isMoved =
true;
}
break;
default:
break;
}
return super.dispatchTouchEvent(ev);
}
/**
* 判断是否滚动到顶部
*/
private boolean isCanPullDown() {
return false;
}
/**
* 判断是否滚动到底部
*/
private boolean isCanPullUp() {
return false;
}
private ScrollListener listener;
public void setListener(ScrollListener listener) {
this.listener = listener;
}
public interface ScrollListener {
void onScroll(
int offset);
}
@Override
protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
return 0;
}
}
转载请注明原文地址: https://ju.6miu.com/read-679101.html