How to control ListView's vertical scroll

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?

Answers


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:

  1. Add an ontouchListener to your ListView
  2. on touch up:

    yourListView.smoothScrollToPosition(LIST_ITEM_INDEX);


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.


Need Your Help

Azure offline sqlite store sync questions related to primary key, data types mapping

java android sqlite azure

I am working on azure offline sync using sqlite. and have couple of questions. I am new to android and azure

Array of Linked Lists C++

c++ arrays pointers data-structures linked-list

So I thought I understood how to implement an array of pointers but my compiler says otherwise =(. Any help would be appreciated, I feel like I'm close but am missing something crucial.