Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ListView Items in Android Scroll one at a Time

Is there any way in which we scroll ListView items only one at a time. Like when you swipe up it'll only scroll One item up and not normal scroll similar for scroll down only one item shifts down.

Please Help!

Here is My Code :

public class ListViewTestExample extends Activity {

    ListView listView;

    private GestureDetectorCompat mDetector;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_list_view_test);

        mDetector = new GestureDetectorCompat(this, new MyGestureListener());
        // Grid ListView object from XML
        listView = (ListView) findViewById(R.id.list);

        mDetector = new GestureDetectorCompat(this, new MyGestureListener());
        // Defined Array values to show in ListView

        String[] values = new String[] { "Android List View",
         "Adapter implementation", "Simple List View In Android",
         "Create List View Android", "Android Example",
         "List View Source Code", "List View Array Adapter",
         "Android Example List View" };

         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
         android.R.layout.simple_list_item_1, android.R.id.text1, values);

         listView.setAdapter(adapter);       
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public boolean onTouchEvent(MotionEvent event) {
        this.mDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        Context context = getApplicationContext();

        public boolean onDown(MotionEvent event) {
                return true;
        }

        public void onLongPress(MotionEvent event) {
            Toast.makeText(context, "Long Press", Toast.LENGTH_SHORT).show();
        }

        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {

            float sensitvity = 50;

            // TODO Auto-generated method stub
            if ((event1.getX() - event2.getX()) > sensitvity) {
                Toast.makeText(context, "Swipe Left", Toast.LENGTH_SHORT)
                    .show();
            } else if ((event2.getX() - event1.getX()) > sensitvity) {
                Toast.makeText(context, "Swipe Right", Toast.LENGTH_SHORT)
                    .show();
            }
            if ((event1.getY() - event2.getY()) > sensitvity) {
                if (event2.getPressure() > event1.getPressure()) {
                    Toast.makeText(context, "Swipe Up + Hold",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "Swipe Up", Toast.LENGTH_SHORT).show();
                }
            } else if ((event2.getY() - event1.getY()) > sensitvity) {
                if (event2.getPressure() > event1.getPressure()) {
                    Toast.makeText(context, "Swipe Down + Hold",
                        Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(context, "Swipe Down", Toast.LENGTH_SHORT).show();
                }
            }
            return true;
        }

        public boolean onSingleTapConfirmed(MotionEvent event) {
            Toast.makeText(context, "Single Tap Confirmed", Toast.LENGTH_SHORT)
                .show();
            return true;
        }

        public boolean onDoubleTap(MotionEvent event) {
            Toast.makeText(context, "Double Tap Confirmed", Toast.LENGTH_SHORT).show();
            return true;
        }

    }

}
like image 486
Vipul Kanade Avatar asked Sep 16 '13 06:09

Vipul Kanade


People also ask

How to programmatically scroll to a specific position in listview in Android?

How to programmatically scroll to a specific position in listView in Android? This example demonstrates how do I programmatically scroll to a specific position in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project.

What is smooth scroll in Android?

Smooth Scroll is a setting in LinearLayoutManager that attempts to smooth the scrollbar’s transition between items. Setting smoothScrollEnabled () to false jumps from one item to the next, adjusting the size of the track for how large the current item is. Too much jumping!

How to fix scrollbar jumping to the end of the list?

If the scroll bar jumping to the end of the list is an issue, a very simple change would be to add a static value to the heightOfScreen. This number can be adjusted based on your use case and expected size of an item.

Can Android scrollbars handle dynamically-sized items in recyclerview?

As an Android developer on The Wall Street Journal, handling lists with content of varying heights is a common use case on Android. Unfortunately, a scrollbar that doesn’t behave erratically is not well supported out of the box when working with dynamically-sized items in a RecyclerView.


1 Answers

I know this is now an old post, but I have searched the net and not really found a solution to this. So I have found a solution that works for me. You need to make a custom ListView and override the dispatchTouchEvent function. My version checks to see if the user has flicked with a min velocity and if they have then smooth scroll to the next item. If under this velocity then check to see if the item is over half way then do a smooth scroll. Otherwise return to the current item. This code assumes that the item fills the view.

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.ListView;

/**
 * Created by bradj on 11/12/13.
 */
public class SingleScrollListView extends ListView
{
    private boolean mSingleScroll = false;
    private VelocityTracker mVelocity = null;
    final private float mEscapeVelocity = 2000.0f;
    final private int mMinDistanceMoved = 20;
    private float mStartY = 0;

    public SingleScrollListView(Context context)
    {
        super(context);
    }

    public SingleScrollListView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public SingleScrollListView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    public void setSingleScroll(boolean aSingleScroll) { mSingleScroll = aSingleScroll; }
    public int getVerticalScrollOffset() { return getFirstVisiblePosition(); }

    @Override
    public boolean dispatchTouchEvent(MotionEvent aMotionEvent)
    {
        if (aMotionEvent.getAction() == MotionEvent.ACTION_DOWN)
        {
            if (mSingleScroll && mVelocity == null)
                mVelocity = VelocityTracker.obtain();
            mStartY = aMotionEvent.getY();
            return super.dispatchTouchEvent(aMotionEvent);
        }

        if (aMotionEvent.getAction() == MotionEvent.ACTION_UP)
        {
            if (mVelocity != null)
            {
                if (Math.abs(aMotionEvent.getY() - mStartY) > mMinDistanceMoved)
                {
                    mVelocity.computeCurrentVelocity(1000);
                    float velocity = mVelocity.getYVelocity();

                    if (aMotionEvent.getY() > mStartY)
                    {
                        // always lock
                        if (velocity > mEscapeVelocity)
                            smoothScrollToPosition(getFirstVisiblePosition());
                        else
                        {
                            // lock if over half way there
                            View view = getChildAt(0);
                            if (view != null)
                            {
                                if (view.getBottom() >= getHeight() / 2)
                                    smoothScrollToPosition(getFirstVisiblePosition());
                                else
                                    smoothScrollToPosition(getLastVisiblePosition());
                            }
                        }
                    }
                    else
                    {
                        if (velocity < -mEscapeVelocity)
                            smoothScrollToPosition(getLastVisiblePosition());
                        else
                        {
                            // lock if over half way there
                            View view = getChildAt(1);
                            if (view != null)
                            {
                                if (view.getTop() <= getHeight() / 2)
                                    smoothScrollToPosition(getLastVisiblePosition());
                                else
                                    smoothScrollToPosition(getFirstVisiblePosition());
                            }
                        }
                    }
                }
                mVelocity.recycle();
            }
            mVelocity = null;

            if (mSingleScroll)
            {
                if (Math.abs(aMotionEvent.getY() - mStartY) > mMinDistanceMoved)
                    return super.dispatchTouchEvent(aMotionEvent);
            }
            else
                return super.dispatchTouchEvent(aMotionEvent);
        }

        if (mSingleScroll)
        {
            if (mVelocity == null)
            {
                mVelocity = VelocityTracker.obtain();
                mStartY = aMotionEvent.getY();
            }
            mVelocity.addMovement(aMotionEvent);
        }

        return super.dispatchTouchEvent(aMotionEvent);
    }
}

So the code simple becomes as below. (Don't forget to change the ListView in the xml to SingleScrollListView) There is no need for a gesture listener.

listView = (SingleScrollListView) findViewById(R.id.list);
listView.setSingleScroll(true);
like image 132
brad J Avatar answered Sep 24 '22 11:09

brad J