I have a ViewPager inside a header of a ListView, and I noticed that, when you're swiping the viewpager, if the finger moves a little bit on the Y axis, the event gets canceled (I guess it's intercepted by the listview?).
The only way to swipe a picture, is to just slide your finger through few pixels, since there'll be less probabilities that you're moving your finger along the Y axis.
Is there a way to make the listview not to intercept the Y axis events in case they happened in the viewpager? I don't even know if this is what I need anyways.
Thanks a lot in advance.
You can try to intercept touch event
Take a look at this post Android - ViewPager scrolling resets
hope it helps
good luck
Related
While I'm reading the source code of android.widget.Scoller, I found the property mMode probably has 2 available value which are SCROLL_MODE = 0; and FLING_MODE = 1; What are the differences between scroll and fling gesture? Can anyone help explain it?
"Scrolling" is a word that can take on different meanings in Android,
depending on the context.
Scrolling is the general process of moving the viewport (that is, the
'window' of content you're looking at). When scrolling is in both the
x and y axes, it's called panning. The sample application provided
with this class, InteractiveChart, illustrates two different types of
scrolling, dragging and flinging:
Dragging is the type of scrolling that occurs when a user drags her finger across the touch screen. Simple dragging is often
implemented by overriding onScroll() in GestureDetector.OnGestureListener. For more discussion of dragging,
see Dragging and Scaling.
Flinging is the type of scrolling that occurs when a user drags and lifts her finger quickly. After the user lifts her finger, you
generally want to keep scrolling (moving the viewport), but decelerate
until the viewport stops moving. Flinging can be implemented by
overriding onFling() in GestureDetector.OnGestureListener, and by
using a scroller object.
I'm currently working on an small Android module and I'm facing a problem which maybe someone can solve. I need to create a calendar and allow the user to select a date range by 1) clicking on a start date (this will create a 2 days range by default) and then 2) touching one range border and dragging it to increase or decrease that range.
Currently I've created all the calendar days cells using a RecyclerView with a GridLayoutManager which has a lot of rows (all the weeks) with 7 items per row (the days). Then I've used the RecyclerView ItemTouchHelper (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.html) and ItemTouchHelper.Callback (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html) to complete the drag&drop functionality. My approach was to use the drag&drop detection provided by those helpers (take a look at https://medium.com/#ipaulpro/drag-and-swipe-with-recyclerview-b9456d2b1aaf#.ib8r012gc) modifying it to avoid moving one item and only detecting the touch+drag+drop gesture I wanted. I've correctly completed the functionality by removing the default drag animation (overriding ItemTouchHelper onDraw/onDrawOver) and using the ItemTouchHelper.Callback callbacks to manage the drag movement (without swapping the adapter items, because I need them always at the same position). All works fine but I'm now facing a problem because the drag detection is not working as expected. I'll try to explain it: if I start the drag movement in the center of a given cell, and I move to the cell to its left, the drag movement isn't triggered until I've reached the center (the same position at where I've started the drag movement) of the left cell. This is a problem because I need to detect a drag as soon as I reach another cell (if the finger is inside the new cell bounds, the drag should be triggered). Another example is: if I start the drag movement in the leftmost side of a cell, the drag won't be triggered until I reach the leftmost side of another cell.
Now I'm trying to play a bit with the ItemTouchHelper.Callback.chooseDropTarget method to manually select the drop target as soon as the fingers enters a new cell but I'm not able to get it work. I think (but I cannot ensure it) that is something strange with the received x,y coordinates.
I know that some code example would be very helpful but I cannot paste it because it belongs to a private and protected repository :(
Any help that anyone could provide to me will be really appreciated. And, of course, I'll try to be pending of this topic to provide all the info I can. I will also take into account new different approaches and suggestions to get the "touch+move+up" movement which I need to move ranges borders :)
Many thanks in advance to all the Stack Overflow community!
After some more research, I found the solution to my problem. I'll post it so if someone faces the same issue, he can find some help here :)
My problem was that I was using the curX and curY parameters returned by ItemTouchHelper.Callback.chooseDropTarget (https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.Callback.html#chooseDropTarget(android.support.v7.widget.RecyclerView.ViewHolder,%20java.util.List%3Candroid.support.v7.widget.RecyclerView.ViewHolder%3E,%20int,%20int)) as if they were the current finger coordinates while dragging, but they are the coordinates of the top leftmost coordinate of the dragged view after applying any translation. Now I feel a bit stupid. I should have read the documentation better :|
As I didn't need that top leftmost coordinate but the finger position, my solution was to use a touch listener attached to the source view so I could detect the initial touch x,y coordinates (relative to that view) using the touchSrcX = MotionEvent.getX() and touchSrcY = MotionEvent.getY() methods and then I applied a point translation before selecting a target in the chooseDropTarget callback. I mean, something like:
curX += touchSrcX
curY += touchSrcY
If someone needs more details or a better explanation, please, contact me and I'll be pleased to help! :)
What is the difference between onScroll() and onFling() in the GestureDetector interface?
When I print out the events they are showing the exact same things. At least the last onScroll() and the onFling().
The only true difference I noticed is that onScroll() is called much more often, fling always just one time.
The difference between Scroll and fling
onFling: is that the user lifts his finger in the end of the movement (that is the reason for what onFling is called one time).
onScroll: is the general process of moving the viewport (that is, the 'window' of content you're looking at).
Understand Scrolling Terminology "Scrolling" is a word that can take on different meanings in Android, depending on the context.
Scrolling is the general process of moving the viewport (that is, the
'window' of content you're looking at). When scrolling is in both the
x and y axes, it's called panning. The sample application provided
with this class, InteractiveChart, illustrates two different types of
scrolling, dragging and flinging:
Dragging is the type of scrolling that occurs when a user drags her
finger across the touch screen. Simple dragging is often implemented
by overriding onScroll() in GestureDetector.OnGestureListener. For
more discussion of dragging, see Dragging and Scaling.
Flinging is the type of scrolling that occurs when a user drags and lifts her finger
quickly. After the user lifts her finger, you generally want to keep
scrolling (moving the viewport), but decelerate until the viewport
stops moving. Flinging can be implemented by overriding onFling() in
GestureDetector.OnGestureListener, and by using a scroller object.
I need to change an image when the user swipes from left to right; that's why I have used SimpleOnGestureListener to detect a swipe event on an ImageView.
In this process, when I swipe an image slowly, the onScroll() method calls frequently and every thing is working fine but when I swipe this image fastly, the onScroll() method called hardly only two three times, please let me know what should I use to make the onScroll() method called according swipe's speed.
As there's much detail to say, I post my answer here rather than adding comments.
onFling gives you four useful parameters : two MotionEvent and two velocity numbers. With these useful information you can call fling on a Scroller. The scroller object will do the rest work for you (e.g. get current x/y value after some time).
For your case, you could call computeScrollOffset and getCurrX/getCurrY to deal with your "swipe animation". Just change your showing image when the View's x/y reaches the boundary.
For instance , suppose your pointer up position is (0,0) and initial x velocity is 1000 pix/second. After 500 milliseconds, you call computeScrollOffset (it will return true certainly) and getCurrX might return 600 (because fling doesn't go linearly).The exact time to change the image is up to you.
For detail usage of Scroller there should be a lots of examples out there. One good example is certainly the official training lession
I can think of other ways of achieving what you want
onFling() gives you the velocity of X and Y: if it's greater than 4000 it counts as a fast scroll, then you can animate the continuous image, its effect like fast swiping.
I have some text content in a scrollable container and I want the user to be able to scroll it having the nice effect of it moving according to the swipe velocity and to keep scrolling until the user taps it. (as many applications for mobile touch screens).
I am thinking to combine events to do it. I will catch the swipe to know the direction, have mouse in and out to see velocity and legth of the swipe, and then keep scrolling with a proportional velocity and length until the user taps the screen.
Does my idea makes sense? (I donĀ“t want to do the work and find out it was really simple and I just didn{t knew how)
Thanks in advance
Maria
A scroller will achieve this for you:
<s:Scroller left="0" right="0" top="0" bottom="0">
<s:VGroup>
<!-- Your content e.g. -->
<s:TextInput/>
</s:VGroup>
</s:Scroller>
Click the screen and drag in the direction. Tap to stop the movement or wait till it ends.