Search code examples
androidandroid-scrollview

Make a scrollView autoscroll with drag and drop in Android


I searched all over, but could not find a solution.

I have a view (lets call it myView) inside a scrollview. myView is bigger than the screen. Since I'm able to get the relative x,y position of my finger inside myView, I would like to make the scrollView autoscroll to the top/bottom when my finger enters a certain top/bottom threshold. I have some ideas, namely translating the drag location to the screen position but this did not solve this problem.

thanks in advance

cheers


Solution

  • All right I figured it out by myself.

    First I had to extend the ScrollView class and added an interface OnScrollViewListener.

    public class MyScrollView extends ScrollView {
        private OnScrollViewListener mListener;
    
        public MyScrollView(Context c, AttributeSet attrs) {
           super(c, attrs);
        }
    
        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
           super.onScrollChanged(l, t, oldl, oldt);
           if (mListener != null) {
               mListener.onScrollChanged((OnScrollViewListener) this);
           }
        }
    
    
        public void setOnScrollViewListener(OnScrollViewListener listener) {
           mListener = listener;
        }
    
    
        public static interface OnScrollViewListener {
           public void onScrollChanged(OnScrollViewListener listener);
        }
    }
    

    Next in my Activity I inserted a member mScrollDistance that indicates the amount of pixels the user scrolls.

    public class ScrollActivity extends Activity {
       private int mScrollDistance;
    
       @Override
       protected void OnCreate(...) {
         ...
    
         final MyScrollView myScrollView = (MyScrollView) findViewById(R.id.scroll_view);
         myScrollView.setOnScrollViewListener(new MyScrollView.OnScrollViewListener() {
    
              public void onScrollChanged(OnScrollViewListener listener) {
                 mScrollDistance = listener.getScrollY();
              }
         }
    
         // making an drag and drop in an view that is inside the MyScrollView
         final LinearLayout myLayout = (LinearLayout)findViewById(R.id.linear_layout);
         myLayout.setOnDragListener(new View.OnDragListener() {
           public boolean onDrag (View v, DragEvent event) {
             int action = event.getAction();
             switch(action) {
                case DragEvent.ACTION_DRAG_STARTED: {
                }
                case DragEvent.ACTION_DRAG_LOCATION: {
    
                  int y = Math.round(event.getY());
                  int translatedY = y - mScrollDistance;
                  int threshold = 50;
                  // make a scrolling up due the y has passed the threshold
                  if (translatedY < threshold) {
                     // make a scroll up by 30 px
                     myScrollView.scrollBy(0, -30);
                  }
                  // make a autoscrolling down due y has passed the 500 px border
                  if (translatedY + threshold > 500) {
                     // make a scroll down by 30 px
                     myScrollView.scrollBy(0, 30);
                  }
                  // listen for more actions here
                  // ...
                }
             }
           }
         }
    

    Now, mScrollDistance gets always a new value and the drag location will be translated to the view location. I tested this and it works on layouts/views that are bigger than the screen size.

    Hope that helps.