下面列出了android.view.VelocityTracker#obtain ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Start a fake drag of the pager.
*
* <p>A fake drag can be useful if you want to synchronize the motion of the ViewPager
* with the touch scrolling of another view, while still letting the ViewPager
* control the snapping motion and fling behavior. (e.g. parallax-scrolling tabs.)
* Call {@link #fakeDragBy(float)} to simulate the actual drag motion. Call
* {@link #endFakeDrag()} to complete the fake drag and fling as necessary.
*
* <p>During a fake drag the ViewPager will ignore all touch events. If a real drag
* is already in progress, this method will return false.
*
* @return true if the fake drag began successfully, false if it could not be started.
*
* @see #fakeDragBy(float)
* @see #endFakeDrag()
*/
public boolean beginFakeDrag() {
if (mIsBeingDragged) {
return false;
}
mFakeDragging = true;
setScrollState(SCROLL_STATE_DRAGGING);
mInitialMotionX = mLastMotionX = 0;
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
} else {
mVelocityTracker.clear();
}
final long time = SystemClock.uptimeMillis();
final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0);
mVelocityTracker.addMovement(ev);
ev.recycle();
mFakeDragBeginTime = time;
return true;
}
/**
* Start a fake drag of the pager.
*
* @return true if the fake drag began successfully, false if it could not be started.
*/
public boolean beginFakeDrag() {
if (mIsBeingDragged) {
return false;
}
mFakeDragging = true;
setScrollState(SCROLL_STATE_DRAGGING);
if (isHorizontal()) {
mInitialMotionX = mLastMotionX = 0;
} else {
mInitialMotionY = mLastMotionY = 0;
}
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
} else {
mVelocityTracker.clear();
}
final long time = SystemClock.uptimeMillis();
final MotionEvent ev = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, 0, 0, 0);
mVelocityTracker.addMovement(ev);
ev.recycle();
mFakeDragBeginTime = time;
return true;
}
private void initView(Context context) {
setOrientation(VERTICAL);
mRefreshStatus = REFRESH_STATUS_NONE;
mScroller = new Scroller(context);
mScreenHeight = Resources.getSystem().getDisplayMetrics().heightPixels;
mVelocityTracker = VelocityTracker.obtain();
ViewConfiguration configuration = ViewConfiguration.get(context);
mMinVelocity = configuration.getScaledMinimumFlingVelocity();
}
public imgSlider(Context context, int width, int height) {
super(context, width, height);
setBackgroundColor(itemBack.Color0);
Vx = VelocityTracker.obtain();
btm = creatImg();
addView(btm);
top = creatImg();
addView(top);
FMTop = new FMView(getContext(),width,height);
FMTop.setBackgroundColor(0x66000000);
FMTop.setClickable(false);
addView(FMTop);
Ui.ef.playerEvent.addEvent(new EventCall(new int[]{playerEvents.SONG_CHANGED,playerEvents.PLAYLIST_CHANGED, Ui.ef.Event_onBind}){
@Override
public void onCall(int eventId) {
if(eventId == playerEvents.SONG_CHANGED){
songChanged();
}
if(eventId == Ui.ef.Event_onBind || playerEvents.PLAYLIST_CHANGED == eventId){
if(Ui.ef.MusicPlayer.handler.list!= null){
songChanged();
}
}
}
});
}
@SuppressWarnings("WeakerAccess") /* synthetic access */
void obtainVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
}
mVelocityTracker = VelocityTracker.obtain();
}
/**
* Used to create a new DragLayer from XML.
*
* @param context The application's context.
*/
public DragController(Launcher launcher) {
Resources r = launcher.getResources();
mLauncher = launcher;
mHandler = new Handler();
mScrollZone = r.getDimensionPixelSize(R.dimen.scroll_zone);
mVelocityTracker = VelocityTracker.obtain();
float density = r.getDisplayMetrics().density;
mFlingToDeleteThresholdVelocity =
(int) (r.getInteger(R.integer.config_flingToDeleteMinVelocity) * density);
}
private void startWheelDrag(MotionEvent event, float x, float y) {
mIsDraggingWheel = true;
mDraggedAngle = 0f;
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
} else {
mVelocityTracker.clear();
}
mVelocityTracker.addMovement(event);
mAngularVelocity = 0f;
mLastTouchAngle = mWheelBounds.angleToDegrees(x, y);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (!isCanMove){
return super.onInterceptTouchEvent(ev);
}
final ViewParent parent = getParent();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if (isVertical()){
mLastPos = ev.getY();
}else {
mLastPos = ev.getX();
}
//拿到上次的down坐标
if (isVertical()){
mMovePos = ev.getY();
}else {
mMovePos = ev.getX();
}
if (mScroller != null && !mScroller.isFinished()) {
mScroller.abortAnimation();
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(ev);
//如果能滚动,应该要屏蔽父控件的触摸事件
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
break;
case MotionEvent.ACTION_MOVE:
float offset;
if (isVerticalMove()){
offset = ev.getY() - mLastPos;
}else{
offset = ev.getX() - mLastPos;
}
if (Math.abs(offset) >= mTouchSlop) {
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
if (mVelocityTracker == null){
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(ev);
//由父控件接管触摸事件
return true;
}
if (isVerticalMove()){
mLastPos = ev.getY();
}else {
mLastPos = ev.getX();
}
break;
default:
break;
}
return super.onInterceptTouchEvent(ev);
}
private void obtainVelocityTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
}
mVelocityTracker = VelocityTracker.obtain();
}
private boolean processTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
mVelocityTracker = VelocityTracker.obtain();
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
mIsDragging = false;
break;
case MotionEvent.ACTION_MOVE:
final float x = getActiveX(ev);
final float y = getActiveY(ev);
final float dx = x - mLastTouchX, dy = y - mLastTouchY;
if (!mIsDragging) {
// Use Pythagoras to see if drag length is larger than
// touch slop
mIsDragging = Math.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
}
if (mIsDragging) {
mListener.onDrag(dx, dy);
mLastTouchX = x;
mLastTouchY = y;
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
}
break;
case MotionEvent.ACTION_CANCEL:
mActivePointerId = INVALID_POINTER_ID;
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
case MotionEvent.ACTION_UP:
mActivePointerId = INVALID_POINTER_ID;
if (mIsDragging) {
if (null != mVelocityTracker) {
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
// Compute velocity within the last 1000ms
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker
.getYVelocity();
// If the velocity is greater than minVelocity, call
// listener
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
mListener.onFling(mLastTouchX, mLastTouchY, -vX,
-vY);
}
}
}
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
case MotionEvent.ACTION_POINTER_UP:
final int pointerIndex = Util.getPointerIndex(ev.getAction());
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = ev.getPointerId(newPointerIndex);
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
}
break;
}
mActivePointerIndex = ev
.findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId
: 0);
return true;
}
/**
* 初始化VelocityTracker
*/
private void initVelocityTrackerIfNotExists() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
}
public ConditionallyEnabledViewPager(Context context) {
super(context);
gestureDetectorListener = new SwipeToCloseListener(context);
gestureDetector = new GestureDetector(context, gestureDetectorListener);
velocityTracker = VelocityTracker.obtain();
}
private void initVelocityTrackerIfNotExists() {
if ( mVelocityTracker == null ) {
mVelocityTracker = VelocityTracker.obtain();
}
}
private void initVelocityTrackerIfNotExists() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
}
private void initVelocityTrackerIfNotExists() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
// 初始化速度追踪器
if (mVelocity == null) {
mVelocity = VelocityTracker.obtain();
}
mVelocity.addMovement(event);
// 设置触碰点
setTouchPoint(x, y);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isRunning = false;
// 设置起始点
setStartPoint(x, y);
// 停止动画
abortAnim();
break;
case MotionEvent.ACTION_MOVE:
mVelocity.computeCurrentVelocity(VELOCITY_DURATION);
isRunning = true;
// 进行刷新
mView.postInvalidate();
break;
case MotionEvent.ACTION_UP:
isRunning = false;
// 开启动画
startAnim();
// 删除检测器
mVelocity.recycle();
mVelocity = null;
break;
case MotionEvent.ACTION_CANCEL:
try {
mVelocity.recycle(); // if velocityTracker won't be used should be recycled
mVelocity = null;
} catch (Exception e) {
e.printStackTrace();
}
break;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction();
final int x = (int) event.getX();
final int y = (int) event.getY();
logD("onTouchEvent: action=%d", action);
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
mScroller.forceFinished(true);
mDownX = x;
isMoved = false;
break;
case MotionEvent.ACTION_MOVE:
final int dx = x - mLastX;
// 判断是否已经滑动
if (!isMoved) {
final int dy = y - mLastY;
// 滑动的触发条件:水平滑动大于垂直滑动;滑动距离大于阈值
if (Math.abs(dx) < Math.abs(dy) || Math.abs(x - mDownX) < TOUCH_SLOP) {
break;
}
isMoved = true;
}
mCurrentDistance += -dx;
calculateValue();
break;
case MotionEvent.ACTION_UP:
// 计算速度:使用1000ms为单位
mVelocityTracker.computeCurrentVelocity(1000, MAX_FLING_VELOCITY);
// 获取速度。速度有方向性,水平方向:左滑为负,右滑为正
int xVelocity = (int) mVelocityTracker.getXVelocity();
// 达到速度则惯性滑动,否则缓慢滑动到刻度
if (Math.abs(xVelocity) >= MIN_FLING_VELOCITY) {
// 速度具有方向性,需要取反
mScroller.fling((int)mCurrentDistance, 0, -xVelocity, 0,
0, (int)mNumberRangeDistance, 0, 0);
invalidate();
} else {
scrollToGradation();
}
break;
default:
break;
}
mLastX = x;
mLastY = y;
return true;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mVelocityTracker = VelocityTracker.obtain();
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
} else {
Log.i(LOG_TAG, "Velocity tracker is null");
}
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
mIsDragging = false;
break;
}
case MotionEvent.ACTION_MOVE: {
final float x = getActiveX(ev);
final float y = getActiveY(ev);
final float dx = x - mLastTouchX, dy = y - mLastTouchY;
if (!mIsDragging) {
// Use Pythagoras to see if drag length is larger than
// touch slop
mIsDragging = FloatMath.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
}
if (mIsDragging) {
mListener.onDrag(dx, dy);
mLastTouchX = x;
mLastTouchY = y;
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
}
break;
}
case MotionEvent.ACTION_CANCEL: {
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
case MotionEvent.ACTION_UP: {
if (mIsDragging) {
if (null != mVelocityTracker) {
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
// Compute velocity within the last 1000ms
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker
.getYVelocity();
// If the velocity is greater than minVelocity, call
// listener
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
mListener.onFling(mLastTouchX, mLastTouchY, -vX,
-vY);
}
}
}
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mVelocityTracker = VelocityTracker.obtain();
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
} else {
Log.i(LOG_TAG, "Velocity tracker is null");
}
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
mIsDragging = false;
break;
}
case MotionEvent.ACTION_MOVE: {
final float x = getActiveX(ev);
final float y = getActiveY(ev);
final float dx = x - mLastTouchX, dy = y - mLastTouchY;
if (!mIsDragging) {
// Use Pythagoras to see if drag length is larger than
// touch slop
mIsDragging = FloatMath.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
}
if (mIsDragging) {
mListener.onDrag(dx, dy);
mLastTouchX = x;
mLastTouchY = y;
if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
}
break;
}
case MotionEvent.ACTION_CANCEL: {
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
case MotionEvent.ACTION_UP: {
if (mIsDragging) {
if (null != mVelocityTracker) {
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
// Compute velocity within the last 1000ms
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000);
final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker
.getYVelocity();
// If the velocity is greater than minVelocity, call
// listener
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
mListener.onFling(mLastTouchX, mLastTouchY, -vX,
-vY);
}
}
}
// Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
}
return true;
}
private void initVelocityTrackerIfNotExists() {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
}