弹性
Posted 我的小侯子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了弹性相关的知识,希望对你有一定的参考价值。
package com.hou.mask;
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;
/**
*
*/
public class ReboundScrollView extends ScrollView
private static final String TAG = "MaskScrollView";
private static final int INVALID_POINTER = -1;
private static final int FACTOR = 2;//因子,阻尼系数
private View childView;
private int mActivePointerId;
private float mLastMotionY;
private float lastDeltaY;
private Rect normal = new Rect();
private int mTouchSlop;
private static final int ALL = 0;
private static final int NONE = 1;
private static final int TOP = 2;
private static final int BOTTOM = 3;
private int elasticity;
public ReboundScrollView(Context context)
this(context, null);
public ReboundScrollView(Context context, AttributeSet attrs)
this(context, attrs, 0);
public ReboundScrollView(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = configuration.getScaledTouchSlop();
elasticity = ALL;
@Override
protected void onFinishInflate()
super.onFinishInflate();
childView = getChildAt(0);
@Override
public boolean onInterceptTouchEvent(MotionEvent ev)
int action = ev.getAction();
if (action == MotionEvent.ACTION_MOVE && Math.abs(ev.getY() - mLastMotionY) > mTouchSlop)
return true;
else if (action == MotionEvent.ACTION_DOWN)
if (getChildCount() == 0)
return false;
mLastMotionY = ev.getY();
mActivePointerId = ev.getPointerId(0);
lastDeltaY = 0;
return super.onInterceptTouchEvent(ev);
@Override
public boolean onTouchEvent(MotionEvent ev)
int actionMasked = MotionEventCompat.getActionMasked(ev);
switch (actionMasked)
case MotionEvent.ACTION_DOWN:
if (getChildCount() == 0)
return false;
mLastMotionY = ev.getY();
mActivePointerId = ev.getPointerId(0);
lastDeltaY = 0;
break;
case MotionEvent.ACTION_MOVE:
int activePointerIndex = ev.findPointerIndex(mActivePointerId);
if (activePointerIndex == -1)
Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
break;
final float y = ev.getY(activePointerIndex);
float deltaY = mLastMotionY - y;
//<0只是上边有弹性,>0只是下边有弹性,不加上下都有
if (elasticity == ALL || elasticity == TOP && deltaY < 0 || elasticity == BOTTOM && deltaY > 0)
if (normal.isEmpty())
//记录原始位置,用来恢复
normal.set(childView.getLeft(), childView.getTop(), childView.getRight(), childView.getBottom());
int offsetY = (int) ((lastDeltaY - deltaY) / FACTOR);
childView.layout(childView.getLeft(), childView.getTop() + offsetY,
childView.getRight(), childView.getBottom() + offsetY);
lastDeltaY = deltaY;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
animateToBack();
mActivePointerId = INVALID_POINTER;
break;
case MotionEvent.ACTION_POINTER_DOWN:
int index = ev.getActionIndex();
mLastMotionY = ev.getY(index);
mActivePointerId = ev.getPointerId(index);
lastDeltaY = 0;
break;
case MotionEvent.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId));
final float upY = ev.getY(ev.findPointerIndex(mActivePointerId));
lastDeltaY = mLastMotionY - upY;
break;
return super.onTouchEvent(ev);
private void animateToBack()
TranslateAnimation animation = new TranslateAnimation(0, 0, childView.getTop() - getPaddingTop(), normal.top - getPaddingTop());
animation.setDuration(200);
childView.startAnimation(animation);
childView.offsetTopAndBottom(normal.top - childView.getTop());
normal.setEmpty();
private void onSecondaryPointerUp(MotionEvent ev)
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId)
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastMotionY = ev.getY(newPointerIndex);
mActivePointerId = ev.getPointerId(newPointerIndex);
以上是关于弹性的主要内容,如果未能解决你的问题,请参考以下文章