I have added one view in linear layout and I want to move that view at run time in the direction user pushed it, for that I have added onTouchListner on view, as well as I have defined one gesture detector.
On gestureDetector's onFling method I have started translation animation on view
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
mX = e2.getX();
mY = e2.getY();
TranslateAnimation transA = new TranslateAnimation(
e1.getX(),e2.getX(),e1.getY(),e2.getY());
transA.setDuration(1000);
transA.setAnimationListener(MainActivity.this);
mBtn.startAnimation(transA);
return super.onFling(e1, e2, velocityX, velocityY);
}
translation animation works well but after animation view remains on its original position. To move view to destination location I am setting views x & y property to mX and mY
#Override
public void onAnimationEnd(Animation animation) {
mBtn.setX(mX);
mBtn.setY(mY);
}
but this is not working properly. please help, If there is any other way to achieve this please let me know.
Is there a button that is moving in there as well? I see a mBtn. Note that a view animation is only going to transform the place where a view is drawn and not where it actually is (hence a button clickable area won't move with a button). You could try doing transA.setFillAfter(true), that should stop it from going back to the original position, but I believe the clickable area will stay the same. Hence you should try doing a property animation, as it will update the properties of the view and not just where it is drawn. Doing a viewpropertyanimator might be easiest as you are animating x and y. You can read more here: http://developer.android.com/guide/topics/graphics/prop-animation.html
Related
I have been creating a Gallery derivative that uses a limited number of Views and, as such, the Adapter needs to be able to populate these Views ahead of time during a scroll or a fling. To do this, I need to get the direction of motion from the onFling(...) and onScroll(...) events.
How can I use the distanceX parameter in onScroll(...) and the velocityX parameter in onFling(...) to determine which way the Gallery is travelling, and therefore which View to prepare next?
The signs of the velocity parameters in onFling(...) and the distance parameters on onScroll(...) are opposite. In order to correctly determine which direction a Gallery is moving, the code should be as follows:
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
//if distanceX is POSITIVE, the Views are travelling left
//therefore the selection position is INCREASING
return super.onScroll(e1, e2, distanceX*mVelocityFactor, distanceY*mVelocityFactor);
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//if velocityX is NEGATIVE, the Views are travelling left
//therefore the selection position is DECREASING
return super.onFling(e1, e1, velocityX*mVelocityFactor, velocityY*mVelocityFactor);
}
By the way, mVelocityFactor is just a constant I introduced to make the scroll/fling a little less energetic. I found 0.6 to be quite a nice value—it still feels intuitive to scroll but the flings are less violent.
I need to build something like a stream for my android app (like pulse)
I tried several horizontalListview or HorizontalScrollView but it's not smooth at all!
The smoother widget I found is the gallery.
I successfully tweaked it to right align:
http://cl.ly/0a3Q002u3H1f3w2l0g2e
My problem is when you scroll max to the right. It looks like stream #3.
Is there a way change this to avoid the gap on the right ?
Maybe to changing the maximum selectable position (# of elements - 4 in my case)
Thank you.
Actually I use this one https://github.com/vieux/Android-Horizontal-ListView
I found the problem about smoothness. The vertical listview shouldn't react when we are already scrolling a stream horizontally.
You could try something like
public class GalleryChild extends Gallery {
...
#Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
if (getSelectedItemPosition() >= getChildCount() - BUFFER) {
setSelection(getChildCount() - BUFFER, true);
/** Eat the event. */
return true;
} else return super.onScroll(e1, e2, distanceX, distanceY);
}
I have a wevbiew with a number of 'pages' (columns of text) in it, and want to be able to scroll horizontally between columns in response to Fling gestures. I can do this fine using scrollTo(), but that is rather sudden and I'd really like to be able to do a smooth transition from one 'page' to the next.
The problem as I see it: you can't attach a Scroller to a WebView, and shouldn't nest a WebView in a ScrollView.
Does anyone have any good ideas for implementing smooth or animated horizontal scrolling in a WebView?
Edited to add: I'm trying to implement an idea of knotmanish's where I use an unattached Scroller to compute the distance..
// vx and vy are from the onfling event of the gesture detector
scroller.fling(page*x, 0, vx, vy, page*(x + 1), page*(x + 1), 0, 0);
while(scroller.computeScrollOffset()){
webview.scrollTo(scroller.getCurrX(), 0);
webview.invalidate();
}
... but the while loop seems too slow to capture the scroller's movement, or something, because the behavior looks just like the scrollTo() method (the view jump to the end of the scroll).
You cannot attach a scroller to a webview however you can make use of the gesture to do the same.
The gesture detects the fling using this method
onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
Give the velocityX, velocityY to the scoller method along with other parameters
fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)
scan the computeScrollOffset() value to find the getCurrX(),getCurrY() positions.
Extend the webview and override the methods onTouchEvent(MotionEvent ev), dispatchTouchEvent(MotionEvent ev) to return false so that by default the touch events are not consumed by the webview itself.
Now implement the gestureListener and override the onfling method mentioned above.
pass the velocity and other parameters to the scroller.
Start a loop to scan the computeScrollOffset() value to find the getCurrX() and getCurrY() and invalidate the view each time.
Pass this value to scroll the webview as needed.
Please let me know in case you need anything.
I would like to get access to the area covered by a finger for each touch event on an Android.
Every touch event will result in a coordinate pair X and Y independent of how big the finger and consequently the touch area is that triggered the event.
I was wondering if there is a way to get the area data which triggered the touch event e.g. size or coordinates NOT
Any help is much appreciated.
Thanks in advance for you answer or redirects,
Christian
The method motionEvent.getSize() should give you what you want (but the level of accuracy may vary depending on the device's screen).
You need to implement OnGestureListener.
First of all, you need to register GestureDetector in onTouchEvent
#Override
public boolean onTouchEvent(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
return true;
}
In onShowPress you will get starting points
#Override
public void onShowPress(MotionEvent e) {
startX = e.getX();
startY = e.getY();
}
In onScroll you will get the end points.
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
endX = e2.getX();
endY = e2.getY();
}
I have an Android app with a ListActivity in the main view. The list contains a LinearLayout with a TextView and a hidden delete Button. The delete Button will be hidden by default. I want to use a fling gesture to show the button. I am able to detect the fling gesture thanks to question #937313 on stackoverflow. It's not clear to me how to determine which item in the list was flung, since the onTouch listener listens to the ListView. The item is not necessarily selected so getSelected* methods can't be used reliably. I am using the SimpleListAdaptor so I don't have direct access to the View Objects in the ListView.
Any ideas?
Try using AbsListView.pointToPosition() to determine the list item for the X,Y coordinate in your list view.
If you're using the recipe from #937313, you should be able to override onFling() more or less as follows:
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
try {
Toast.makeText(listAdapter.getItem( listView.pointToPosition( (int) e1.getX(), (int) e1.getY() ).toString() );
return super.onFling();
} catch( Exception e ) {
// do nothing
}
}