How to control ListView's vertical scroll - android

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);

Related

Vertical viewpager with vertical scrollview

I'm trying to use a vertical scrollview in conjunction with a vertical viewpager (see https://github.com/kaelaela/VerticalViewPager), and I'm not sure how to tackle it.
Essentially, I have two fragments, one lower fragment (the one that is defaulted to when the activity starts) which contains a full-screen scrollview, and one upper fragment which I want to reach when the user is at the top of the lower fragment's scrollview and continues to pull down. If anyone has used Facebook messenger, it's similar to their functionality where if you continue to scroll down on their chats page, the camera is started.
Right now, the scrollview blocks the action of opening the second fragment unless i pull down from a very specific angle.
I've considered implementing something using the OnOverScroll method of the scrollview (if Y scroll position is 0), but I feel that would lead to a bad UX because even the slightest overscroll would pull down a whole new fragment.
If anyone has any ideas, I'd be really grateful.
Thanks a lot.
I solved my issue by wrapping my scrollview in a SwipeRefreshLayout. Here are the steps, to help anyone that runs into this issue in the future:
After wrapping your scrollview in the SwipeRefreshLayout, set the layout to transparent in code using mySwipeRefreshLayout.setColorSchemeColors.
Then use
mySwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
// do your pull-down task here
}
});
to listen for when the user pulls down their scrollview from the top.
Slightly hacky solution but avoids writing custom class extensions that could introduce bugs and uses an existing feature to pretty nicely achieve the desired outcome.

Differentiate between scroll and swipe in Flex Mobile Application

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?

Scroll ListView smoothly and programmatically

I have searched a lot but I couldn't find an answer.
I want to implement something like in Go Launcher. When you drag an icon in app drawer and move it out of container top or bottom bound, the list begins to scroll.
So far, I have tried following things:
Dispatch touch events to simulate scrolling - impossible while touching the screen
Use smoothScrollBy() method - almost there, but it scrolls only screen height distance
Use scrollBy() - it moves only the container and leaves blank space. I would put there some rows if only I could be able to reuse views that went off the screen.
I need the ListView to scroll SMOOTHLY.
So here goes ma question. Anybody knows how can it be done? I'll put a gratitude in About section of my app to person who will help me:)
using listview and try scrollToPosition(),or smoothscrollBy()

Need help animating an Android ListView

I have a ListView in my Android application. The individual views in the list are a little bit smaller than the size of the screen.
I want the list to always show one item centered in the screen, with just a small sliver of the previous and next items showing above and below it.
When the user scrolls, I need to reposition the child view at position 0 or 1 (depending on which way they are scrolling). Currently I am doing this by calling "setSelectionFromTop" in my onScrollStateChanged method. This works, but the transition is immediate, not smooth. It is jarring and confusing in a lot of cases.
What's the best approach to fixing this? I want to animate the process of scrolling the list into the position I want, but I can't find any methods in ListView or its superclasses that let me directly control the scroll position of the entire list.
I think I could animate it using multiple calls to setSelectionFromTop(int position, int y) with progressive values of y, but I don't know how to determine the initial value of y. Is there some way to get that by interrogating the view object at the designated position?
Another challenge I have in front of me is that I want to animate the removal of an item from the list - by having it either disappear or slide away to the left, and then having the surrounding views move up and down to fill the space. Is there a straightforward and reliable way to do this with a ListView? Should I just give up on the ListView and write the whole thing as a custom view from scratch?
Thanks.
This definitely should be possible. Does smoothScrollToPosition() work?
Otherwise, you can try simulating the touches using TouchUtils.

Android: Next/Previous fling that sticks to the finger similar to Home Screen

I want to give my app a nice touch by allowing users to slide the page left or right instead of just using next/previous buttons (similar to the home screen).
What is the best way to do that? I assume I would have to override one of the Activity.on... methods and that I would also have to put my page's main View in a ViewGroup that allows me to shift pages left and right.
ViewFlipper is your friend!
Here you can see a nice video of the ViewFlipper in action and also a very good tutorial:
http://www.inter-fuser.com/2009/07/android-transistions-slide-in-and-slide.html
The solution is even easier these days with the release of Compatibility Package r3. You can download here: http://developer.android.com/sdk/compatibility-library.html
It includes
ViewPager: A ViewGroup that manages the layout for the child views, which the user can swipe between.
PagerAdapter: An adapter that populates the ViewPager with the views that represent each page.
and Fragment versions of those, if you are that way inclined.
The pager code is compatible back to API version 4 (1.6), and I just implemented a dynamically generated viewPager coming off a dynamically generated ListView in about 2 hours. I'm a novice, so this is definitely the preferred path.
There is an example app here: http://geekyouup.blogspot.com/2011/07/viewpager-example-from-paug.html
If one wants to flip between two activities perhaps one can apply this animated transition:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
finish();
//transition using XML view animations
overridePendingTransition(R.anim.slideinfromright, R.anim.slideouttoleft);
Use GestureDetector to detect if the touch event is a scroll.
If the first event to the first call to onScroll is ACTION_DOWN then you should see if it was a dominantly horizontal scroll. If so then your scroll is started and you should shift the absolute position of the view that fills the page.
For non deprecated absolute positioning, see my answer here Android: Alternative to AbsoluteLayout (I really do need absolute positioning)
You will want to be cautions of whether you return true to consume the touch events or not.
GestureDetector does not have a callback for scrolling having stopped. You will have to check if there was an ACTION_UP before you call GestureDetector.onTouchEvent and if there was an action up and you did have an unfinished scroll then you should set the absolute position to the destination location and use a TranslateAnimation to make it look nice moving from current to destination.
Edit:
GestureDetector did not work well at all if the child views also wanted to respond to touch events. I ended up creating a subclass of FrameLayout (one of the most basic layouts and the closest thing to a non intrusive parent view) and overriding dispatchTouchEvent. I just took all the events and did the detection myself.
cant we use Gallery view here?? with the adapter the whole page can be inflated inside gallery view adapter getView() and it will manage the left right scrolling perfectly.

Categories

Resources