Question

I have a custom ListView that shows items "page by page". So I've written OnTouch method and it works perfect, now I want to write OnFling method that will realize smooth and inertial scrolling of my ListView.

The problem is the scrolling animation of smoothScrollToPosition(int position) isn't smooth, it's very fast. smoothScrollToPosition(int position, int offset, int duration) works, but my minSdk must be 8 and besides this functions place current element badly despite on offset.

This is the code of my OnFling method:

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 
{
        if(null == getAdapter()) return false;

        boolean returnValue = false;
        float pty1 = 0, pty2 = 0;

        if (e1 == null || e2 == null)
            return false;

        pty1 = e1.getY();
        pty2 = e2.getY();

        if (pty1 - pty2 > swipeMinDistance && Math.abs(velocityY) > swipeThresholdVelocity) 
        {
            float currentVelocity = Math.min(Math.abs(velocityY), Math.abs(swipeMaxVelocity));

            final int shift = (int) ((currentVelocity / swipeMaxVelocity) * swipeMaxElements + 1);

            if (activeItem < getAdapter().getCount() - shift - 1)
                activeItem = activeItem + shift;
            else
            {
                activeItem = getAdapter().getCount() - 1;
                return false;
            }

            returnValue = true;
        } 
        else if (pty2 - pty1 > swipeMinDistance && Math.abs(velocityY) > swipeThresholdVelocity) 
        {
            float currentVelocity = Math.min(Math.abs(velocityY), Math.abs(swipeMaxVelocity));

            final int shift = (int) ((currentVelocity / swipeMaxVelocity) * swipeMaxElements + 1);

            if (activeItem >= shift)
                activeItem = activeItem - shift;
            else
            {
                activeItem = 0;
                return false;
            }

            returnValue = true;
        }
        smoothScrollToPosition(activeItem);
        return returnValue;
    }

The xml content is:

<?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/rl_main"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

 <konteh.example.errortest.CardsListView
     android:id="@+id/cardsListView"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_alignParentLeft="true"
     android:layout_alignParentTop="true"
     android:smoothScrollbar="true" 
     />
Was it helpful?

Solution

Solved! My solution is:

    int pixelCount = height * shift * (isForward ? 1 : -1); // calculate approximately shift in pixels
    smoothScrollBy(pixelCount, 2 * DURATION * shift);//this smooth scroll works!
    postDelayed(new Runnable() 
    {
        public void run() 
        {
            smoothScrollBy(0, 0); // Stops the listview from overshooting.
            smoothScrollToPosition(activeItem + 1);
        }
    }, 
    DURATION * shift);

Maybe it's not the best solution, but it works!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top