VelocityTracker giving random seeming results
android, android-relativelayout, touch-event
Solution
I'll have to see your movements with your finger to see if the number matches. Some notes: - The results in emulators are completely inaccurate and unexpected in some cases. - Note that you are not tracking pointers. If at some point there is more than one pressure point in the screen, they might affect the result of the calculation of the velocity tracker.
EDIT: You are right. The events are relative to its view in its initial state (unless you change its layoutParams) what I wouldn't recommend. For what you want to do, scroll should work perfectly, which is somehow what you are doing. What is that you want to achieve? We've recently released a library I've been working on in the last months and my first approach was similar to yours. Instead explore this option:
mScroller.startScroll(sx, sy, dx, dy, duration);
Actually the code you have seems to be enough to achieve what you want. You could just avoid changing the layout params of the view which is not the goal there. It'll help to know what is your goal. Check our library out to see if it's somehow closer: https://github.com/6wunderkinder/android-sliding-layer-lib
You can find a demo app in the appstore here: https://play.google.com/store/apps/details?id=com.slidinglayersample
Let's retake it from here.
EDIT 2: Sneaking into the code of AbsListView of Android's source I saw a way that could work for you. Line 3502:
mFlingRunnable.startOverfling(-initialVelocity);
mFlingRunnable is an object of the class FlingRunnable which is defined in the same AbsListView class and implements from Runnable (http://code.metager.de/source/xref/android/1.6/frameworks/base/core/java/android/widget/AbsListView.java - line 2237). It's a huge bunch of code. There's another example of it in the Gallery class (http://code.metager.de/source/xref/android/1.6/frameworks/base/core/java/android/widget/Gallery.java) in line 1287.
The idea is to use a Runnable as a means of something that re-runs on every frame recalculating and drawing the position of the flinged object.
This might go too complex for your goal. Another idea would be to take the velocity from the velocity tracker on MotionEven.UP or CANCEL and create an animation of the position of the object calculating the destination based on the last velocity registered by the VelocityTracked: sending the object further or nearer depending on the velocity at the time the user move her finger up.
Problem
To get a better understanding of how views work, I'm trying to make a `RelativeLayout` that I can drag around and fling. The idea is to capture `onTouch` events, set the layout parameters of the `RelativeLayout` during `ACTION_MOVE`, and then use a `Scroller` to "fling" the the view on `ACTION_UP`. To track Velocity, I am using a `VelocityTracker`. While the view moves as expected when I drag it around, the `VelocityTracker` is giving seemingly random results. Below is a log snippet of me sliding my finger from left to right across the screen (the two numbers are x and y velocities). As you can see, there are many negative numbers, and the y velocity seems to be larger than it should be. Does anyone know what I might be doing wrong? ``` 03-30 20:37:29.857: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 23.123592 11.537558 03-30 20:37:29.873: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 356.74066 55.184505 03-30 20:37:29.888: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 343.06155 43.027973 03-30 20:37:29.904: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 248.62907 32.232735 03-30 20:37:29.927: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 182.43666 22.957638 03-30 20:37:29.943: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 157.40408 54.90605 03-30 20:37:29.959: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 59.81672 15.241951 03-30 20:37:29.974: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 45.65707 -8.753063 03-30 20:37:29.990: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 62.7431 -23.311165 03-30 20:37:30.005: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 82.24246 -20.412537 03-30 20:37:30.029: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 101.6548 4.1870637 03-30 20:37:30.045: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 35.63154 -25.088724 03-30 20:37:30.060: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -65.35024 8.635846 03-30 20:37:30.076: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 34.84411 12.235493 03-30 20:37:30.091: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 137.96663 -32.02561 03-30 20:37:30.107: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 104.81523 4.6049824 03-30 20:37:30.130: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -15.846537 -23.924715 03-30 20:37:30.146: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 2.1034415 19.266556 03-30 20:37:30.162: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 20.578733 29.17785 03-30 20:37:30.177: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -28.217247 -42.907413 03-30 20:37:30.193: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -0.87727404 -1.170224 03-30 20:37:30.209: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -24.889711 8.474885 03-30 20:37:30.232: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 153.30855 23.77272 03-30 20:37:30.248: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 44.412945 17.595121 03-30 20:37:30.263: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -39.40518 -28.735428 03-30 20:37:30.279: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -58.433273 -2.295834 03-30 20:37:30.295: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 51.650055 -26.379906 03-30 20:37:30.310: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 152.88931 -20.75504 03-30 20:37:30.334: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 16.233286 -44.017315 03-30 20:37:30.349: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 23.231287 18.601854 03-30 20:37:30.365: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 7.3124657 38.14189 03-30 20:37:30.380: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 84.67032 -22.859661 03-30 20:37:30.396: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 22.753403 -6.019523 03-30 20:37:30.412: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 59.714558 -35.091564 03-30 20:37:30.435: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 27.547312 24.507784 03-30 20:37:30.451: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 114.54237 29.865501 03-30 20:37:30.466: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 70.55507 3.2689145 03-30 20:37:30.482: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -2.4525054 -6.8937516 03-30 20:37:30.498: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 17.924507 -40.815117 03-30 20:37:30.521: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 43.035046 0.5026546 03-30 20:37:30.537: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 95.18336 -11.013772 03-30 20:37:30.552: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -58.86387 10.808097 03-30 20:37:30.568: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -15.751452 12.716822 03-30 20:37:30.584: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 6.3607893 -19.160402 03-30 20:37:30.599: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 93.13071 12.679931 03-30 20:37:30.623: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 71.644485 -24.96885 03-30 20:37:30.638: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -12.482128 18.495268 03-30 20:37:30.654: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -107.08017 23.484608 03-30 20:37:30.670: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -1.009377 -20.781479 03-30 20:37:30.685: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 48.203453 0.5582556 03-30 20:37:30.701: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 12.369134 -34.194973 03-30 20:37:30.724: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 20.611326 14.374227 03-30 20:37:30.740: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 120.71236 56.88748 03-30 20:37:30.755: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 149.84518 14.843528 03-30 20:37:30.771: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -129.18591 -13.255397 03-30 20:37:30.787: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -110.96849 -42.02827 03-30 20:37:30.802: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -77.30668 -12.200225 03-30 20:37:30.826: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 44.793446 16.331116 03-30 20:37:30.841: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 30.79781 -47.53295 03-30 20:37:30.857: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -53.739525 -2.9649315 03-30 20:37:30.873: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -86.65882 -16.804096 03-30 20:37:30.888: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 47.278873 52.180782 03-30 20:37:30.904: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 25.044767 32.227722 03-30 20:37:30.927: DEBUG/SlidingListViewRow(21863): ACTION_MOVE 40.374264 -65.27872 03-30 20:37:30.927: DEBUG/SlidingListViewRow(21863): ACTION_MOVE -12.49039 -48.878017 ``` Code: ``` package com.example.SlidingListViewRow; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.Scroller; public class SlidingListViewRow extends RelativeLayout { VelocityTracker mVelocityTracker; Scroller mScroller = new Scroller(getContext()); float mStartX, mStartY; public SlidingListViewRow(Context context) { super(context); } public SlidingListViewRow(Context context, AttributeSet attrs) { super(context, attrs); } public SlidingListViewRow(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean onTouchEvent(MotionEvent event) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { mVelocityTracker.clear(); mScroller.abortAnimation(); Log.d("SlidingListViewRow", "ACTION_DOWN: " + " x:" + event.getX() + " y:" + event.getY()); mStartX = event.getX(); mStartY = event.getY(); mVelocityTracker.addMovement(event); return true; } case MotionEvent.ACTION_MOVE: { mVelocityTracker.addMovement(event); mVelocityTracker.computeCurrentVelocity(1000); float vx = mVelocityTracker.getXVelocity(); float vy = mVelocityTracker.getYVelocity(); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); Log.d("SlidingListViewRow", "ACTION_MOVE\t" + vx + "\t" + vy); lp.leftMargin = (int)(lp.leftMargin + event.getX() - mStartX); lp.topMargin = (int)(lp.topMargin + event.getY() - mStartY); setLayoutParams(lp); return true; } case MotionEvent.ACTION_UP: { mVelocityTracker.computeCurrentVelocity(1000); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); Log.d("SlidingListViewRow", "ACTION_UP: " + mVelocityTracker.getXVelocity() + " " + mVelocityTracker.getYVelocity()); mScroller.forceFinished(true); mScroller.startScroll(lp.leftMargin, lp.topMargin, (int) mVelocityTracker.getXVelocity(), (int) mVelocityTracker.getYVelocity(), 1000); invalidate(); mVelocityTracker.recycle(); mVelocityTracker = null; return true; } case MotionEvent.ACTION_CANCEL: { mVelocityTracker.recycle(); mVelocityTracker = null; } } return super.onTouchEvent(event); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { Log.d("SlidingListViewRow", "computeScroll " + mScroller.getCurrX() + " " + mScroller.getCurrY()); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); lp.leftMargin = mScroller.getCurrX(); lp.topMargin = mScroller.getCurrY(); setLayoutParams(lp); invalidate(); } } } ``` EDIT: I think I've come closer. What appears to be happening is that the motion events are relative to the view, and because I'm moving the view, they just jitter around where I touch the view initially. Logging `event.getX()` and `event.getY()`, I get the following when dragging my finger from top to bottom. Note that x and y are pretty much always the same. So obviously, this approach does not work. Now the question is, how do I get around it? ``` 04-06 10:55:13.460: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:241.85272 vx: 0.008770505 vy:7.7523403 04-06 10:55:13.476: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:244.04398 vx: -0.0014130835 vy:7.125545 04-06 10:55:13.491: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:242.04156 vx: -0.0018627803 vy:-8.498776 04-06 10:55:13.515: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:243.98645 vx: -0.0011581925 vy:-10.778463 04-06 10:55:13.530: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:243.67465 vx: 0.003123357 vy:-0.96067995 04-06 10:55:13.546: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:244.90335 vx: 0.0012589534 vy:20.408503 04-06 10:55:13.562: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:245.38507 vx: 0.0031079662 vy:42.45428 04-06 10:55:13.577: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:246.9231 vx: 0.00393455 vy:20.763577 04-06 10:55:13.616: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:245.3899 vx: 0.0024473427 vy:-15.408336 04-06 10:55:13.632: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:246.62701 vx: 1.6782524E-4 vy:12.024636 04-06 10:55:13.648: DEBUG/SlidingListViewRow(29988): ACTION_MOVE: x:174.0 y:247.16913 vx: 0.0032229617 vy:5.3146386 ```