Is it possible to differentiate between a Horizontal Swipe gesture and a Horizontal Scroll in Flex Mobile.
I have a List (horizontal layout) with no listener attached to it, and a view, with a GestureSwipe listener attached to it, when I try to scroll the list the swipe gesture gets fired, obviously.
I have tried to add a gesture event listener to the list and call a function with event.stopPropagation() which does stop the gesture being fired in the view, but as the list takes up 85% of the screen real-estate this makes it quite difficult to make the view event fire, which defeats the object of what I want to do.
Is there a way to tell the 2 actions apart, speed, duration or something else?
Using FlashDevelop, and Flex SDK v4.14.1, Air 17.0, building for Android
Thanks
I never developed Flex Mobile, but you can differentiate between a Horizontal Swipe gesture and a Horizontal Scroll if you could override interceptOnTouchEvent to get the event;
Ok, so I can't find out how to differentiate between the 2 events, however there seems to be a workaround, not a good one, but I suppose it could work, however I see an issue with adding the event listener after the list has scrolled to it's furthest point, you would require another scroll/swipe action to make the view transition, not a good experience for the users.
list.scroller.viewport.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler );
protected function propertyChangeHandler(event:PropertyChangeEvent):void
{
if (event.property == "horizontalScrollPosition" )
{
if (event.newValue == (event.currentTarget.measuredWidth - event.currentTarget.width )) {
navigator.pushView(view.RightView);
}
if(event.newValue == 0){
navigator.pushView(view.LeftView);
}
}
}
Does anyone have any thoughts on this approach?
Related
I am in a team which is building an app for a tablet which reacts like a magazine.
We're using ListView to display one article having multiple pages.
Each row contains a lot of data, and is used to represent a page of a magazine.
One row takes almost whole of the screen in portrait mode, so one row == one screen
As of now, when a user scrolls this whole ListView, it behaves the way a normal ListView would -
if you flick fast enough, it will scroll fast
if you scroll slowly, scrolling stops as soon as you stop vertical motion of the finger
What I want-
No matter how fast or slow a user scrolls/flicks (makes a finger movement in vertical direction), only one single row should be scrolled.
Is there a way I can control how the ListView is being scrolled?
I searched a lot, quite a number of articles suggesting how to scroll to top or to a particular position, but no one actually tells how the scrolling happens so that I can control it.
Am I missing something?
Well your question is limited specifically to ListView, which I think can be achieved by calculating screen dimensions and thereby acting upon the behaviour but since I'm not sure about ListView technicallity. I do can guide you if I would have implemented I would have taken use of:
1) ViewPager: Which I think is more apt for your current requirements, for which you can find details here -
http://android-developers.blogspot.in/2011/08/horizontal-view-swiping-with-viewpager.html
or
take help of more custom requirements as mentioned on this page -
How to make an Android view that flips between views on swipe/fling
2) Inflating and using animations: Other thing I could have used is to inflate pages at runtime and react upon a particular gesture and also integrating animations on flipping.
But the use of ViewPager will be better over ListViews, AFAIT, if using ListViews is not mandatory for your requirements.
ListView uses a Scroller (OverScroller past GingerBread 2.3) which has private access. Not sure if this will help you out but it can point you in the right direction. To get the behaviour you want you can try the following(I have only tested this on a ScrollView):
//Replace the scroller with your own
Field mScroller;
try {
mScroller = ListView.class.getDeclaredField("mScroller");
mScroller.setAccessible(true);
scroll = new OverScroller(mContext, new DecelerateInterpolator(DECELERATE_AMOUNT));
mScroller.set(yourListView, scroll);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Then add an ontouchlistener to uour ListView and scroll on touch up:
mScroller.startScroll(0, startY, 0, distanceToNextPage, 500);
An alternative to the solution above you can try the following:
Add an ontouchListener to your ListView
on touch up:
yourListView.smoothScrollToPosition(LIST_ITEM_INDEX);
I cant seem to find the answer to this, mainly because I don't know what it is called.
I am going to expand a few features in my app, currently users can touch and drag to move forward in a list of images. What I want is for the users to "swipe" there finger and then all of these images will move under acceleration and will slowly come to a stop.
Is this a gesture? If so is it the "Fling" gesture?
There are several ways to do so.
Use ListView
Use Gallery
Use ScrollView
Use HorizontalScrollView
Write your custom ViewGroup or View
For the last approach, you have to detect the Fling gesture as you said and handle all the scrolling animations involved.
I'm trying to implement a UI with a scrollable component that has a certain resistance to starting the scroll - ie. that you have to drag it a certain number of pixels before the scroll starts. Is this supported in Android, and if not is it something that can be added? The idea is to allow a scrolling component to snap to certain positions and resist being moved from them accidentally.
Yes, but you'll have to listen to motion events and track what's happening yourself.
I need to implement HorizontalScrollView which is scrolled to predefined positions (similar to Home behaviour). It works with slow gestures, but does not work with neither flings nor arrow key press.
I hooked to View.onScrollChanged() and it is called when scrolling happened, but I can't determine when scrolling animation ends.
In theory there should be a way to say that fling movement is over. Is there such API?
I did not find a way to track scroll animation, but it's possible to move scroll logic from HorizontalScrollView class to derived by you, where you can control every aspect of scrolling
I'm replying to a post a year old but this might be useful for future readers.
For implementing HOME-Like scroll, use Gallery instead of HorizontalScrollView.
Using 'Gallery' you need not worry about stopping scrolling at predefined positions and it gives you a handler for Fling-gesture too.
Add your code in onFling() or onScroll() as per your requirement.
More info # http://developer.android.com/reference/android/widget/Gallery.html
The views are not cached in a ViewFlipper. Is there a way wherein we can get an image of the view and show it to user so that he sees the Ui as we see on Home scrren(when we swipe the previous view also moves along and when we lift our finger, only then the next view is shown completely.)
What I want to do is that when the user starts moving his finegr on screen, the view should also move along(create an image of view).
I am not getting to do this, as when we swipe the present view goes and next view comes, we do not get both visible when we r moving our finger on screen.
Please if anyone gets what I am trying to do, do help me.
Thanks,
Farha
It's tricky to get scroll and swipe tracking working on Android, while using ViewAnimator or its subclasses.
They allow you to set in and out animations and start them at a given moment, but they work with discrete, either-this-or-the-other-view animations. They are actually using FrameLayout and after in or out animation is executed, other views' visibility is set to View.GONE to hide them from showing up under/over your current View.
The Launcher and the Gallery application are actually doing the functionality you want, by using a different approach.
They track the user touch input (onTouchEvent()), on MotionEvent.ACTION_MOVE they perform animations manually and on MotionEvent.ACTION_UP snap to the appropriate view, just like in the iPhone.
Unfortunately, this approach is actually more complicated than it looks like.
With the manual handling, you have to ensure that you are taking care of everything related to the touch input. This includes a lot of flag-raising, value-checking, event-delegating, etc.
If you want to get better acquainted with this, take a look at these classes from Gallery3D or Launcher's source code.
One other way to get nice horizontal scrolling is to use HorizontalScrollView.
You have to figure out a way to recycle your views, like you would with a ListView and you have to add the snap-to-view logic, but if you have to take care of a small number of views it could be the easiest approach.
Hope that helps.