In Android how to synchronize scrollview with different scrolling speeds?
<p>I have some dependent scrollview means (when I scroll one view others will also scroll). I am able to do it properly, but now I want to manage the speed of scroll means (when I scroll my scrollview1 than scrollview2 should scroll +10 and scrollview3 should scroll +20 or whatever speed) same for other (scrollview2, and scrollview3) also.</p>

<p>I check there is a method called scrollview.scrollto(x,y). Which used to manage the scroll but when i increase scollto(x, y+scrollviews(i).getSpeed()) than it gives me stackOverflow exception.</p>

<p>I am attaching my code please look into this and give me some suggestion how can solve this problem.</p>

<p>My custom scrollView class is:</p>

<pre><code>public class CustomVerticalObserveScroll extends ScrollView {
    private GestureDetector mGestureDetector;
    View.OnTouchListener mGestureListener;


    public CustomVerticalObserveScroll(Context context, AttributeSet attrs) {
        super(context, attrs);
        mGestureDetector = new GestureDetector(context, new YScrollDetector());
        setFadingEdgeLength(0);
        // TODO Auto-generated constructor stub
    }

    private CustomScrollLisner scrollViewListener = null;

    public CustomVerticalObserveScroll(Context context) {
        super(context);
        mGestureDetector = new GestureDetector(context, new YScrollDetector());
        setFadingEdgeLength(0);
    }

    public CustomVerticalObserveScroll(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        mGestureDetector = new GestureDetector(context, new YScrollDetector());
        setFadingEdgeLength(0);
    }

    public void setScrollViewListener(CustomScrollLisner scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        super.onScrollChanged(x, y, oldx, oldy);
         if (scrollViewListener != null) {
         scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
         }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev)
                &amp;&amp; mGestureDetector.onTouchEvent(ev);
    }

    // Return false if we're scrolling in the x direction
    class YScrollDetector extends SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY) {
            if (Math.abs(distanceY) &gt; Math.abs(distanceX)) {
                return true;
            }
            if (Math.abs(distanceX) &gt; Math.abs(distanceY)) {
                return true;
            }
            return false;
        }
    }

}
</code></pre>

<p>and this code I am using to make scroll dependent scroll views.</p>

<pre><code>public class RelativePanoFeature implements IFeaturetype, OnTouchListener {
    private String type;
    private FeatureCordinates locationCordinates;
    private int mOrientation;
    private String image;
    private FeatureCordinates triggerCordinates;
    private String scrollDirection;
    private String scrollSpeed;
    private String scrollHandler;
    CustomVerticalObserveScroll vertical_scroll;
    CustomHorizontalObserveScroll horizontal_scroll;
    RelativeLayout vsChild;

    long timeonDown, timeonUp;
    Thread t;
    Handler mhandler;
    float downx, downy;

    int touchId;

    public static int scrollid = 0;
    public static ArrayList&lt;RelativePanoHandler&gt; storePanoHandler = new ArrayList&lt;RelativePanoHandler&gt;();

    public RelativePanoFeature(String type) {
        this.type = type;

    }

    @Override
    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String getType() {
        return type;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public String getImage() {
        return image;
    }

    public FeatureCordinates getLocation() {
        return locationCordinates;
    }

    public void setLocation(FeatureCordinates featureCordinates) {
        this.locationCordinates = featureCordinates;
    }

    public void setOrientation(int mOrientation) {
        this.mOrientation = mOrientation;
    }

    public int getOrientation() {
        return mOrientation;
    }

    public FeatureCordinates getTrigger() {
        return triggerCordinates;
    }

    public void setTrigger(FeatureCordinates trigger) {
        this.triggerCordinates = trigger;
    }

    public void setScrollDirection(String scrollDirection) {
        this.scrollDirection = scrollDirection;
    }

    public String getScrollDirection() {
        return scrollDirection;
    }

    public void setScrollSpeed(String scrollSpeed) {
        this.scrollSpeed = scrollSpeed;
    }

    public String getScrollSpeed() {
        return scrollSpeed;
    }

    public void setScrollHandler(String scrollHandler) {
        this.scrollHandler = scrollHandler;
    }

    public String getScrollHandler() {
        return scrollHandler;
    }

    public void setTouchId(int touchid) {
        this.touchId = touchid;
    }

    public int getTOuchId() {
        return touchId;
    }

    /* function to draw relative pano */
    public void drawRelativePano(final Context con,
            final RelativeLayout parent, final Handler handle) {
        /* splitting the path from images key in the string */
        RelativePanoHandler panHandler = new RelativePanoHandler();
        final int height;
        final int width;
        vsChild = new RelativeLayout(con);
        mhandler = handle;

        /* giving size of of vertical scroll's child */
        LayoutParams imageViewLayoutParams = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        vsChild.setLayoutParams(imageViewLayoutParams);

        /* splitting the path from images key in the string */
        String path[] = getImage().split("images");
        try {
            /* Initialise loader to load the image inside child */
            BackgroundImageLoader loader = new BackgroundImageLoader(vsChild,
                    Property.FILEPATH + path[1], con);
            try {
                loader.execute();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
            /* getting height and width of image from loader object */
            height = loader.get().getHeight();
            width = loader.get().getWidth();
            /*
             * condition for putting the child view in vertical scroll and
             * implementing the multi directional scroll for event pano
             */
            int locWidth = getLocation().getWidth(), locHeight = getLocation()
                    .getHeight();
            System.out.println("Width= " + width + " Location width= "
                    + locWidth);

            System.out.println("Heoght= " + height + " Location Height= "
                    + locHeight

            );

            if (width &gt; (getLocation().getWidth())
                    || height &gt; (getLocation().getHeight())) {

                vertical_scroll = new CustomVerticalObserveScroll(con);
                horizontal_scroll = new CustomHorizontalObserveScroll(con);

                vertical_scroll.setFillViewport(true);
                horizontal_scroll.setFillViewport(true);

                vertical_scroll.setId(scrollid);

                horizontal_scroll.setFadingEdgeLength(0);

                /*
                 * adding the soft later on vertical and horizontal scroll if
                 * the detected device is on api level 10 or more than that
                 */
                if (Build.VERSION.SDK_INT &gt; 10) {
                    vertical_scroll
                            .setLayerType(View.LAYER_TYPE_SOFTWARE, null);
                    horizontal_scroll.setLayerType(View.LAYER_TYPE_SOFTWARE,
                            null);
                }

                vsChild.setEnabled(true);

                /*
                 * parameters for setting the height and width of vertical
                 * scroll
                 */
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                        getLocation().getWidth(), getLocation().getHeight());
                params.leftMargin = getLocation().getX();
                params.topMargin = getLocation().getY();
                vertical_scroll.setLayoutParams(params);

                /* adding vertical scroll child this child will hold the image */
                vertical_scroll.addView(vsChild, width, height);
                horizontal_scroll.setLayoutParams(params);
                /*
                 * adding vertical scroll as a child of horizontal scroll for
                 * multidirectional scrolling
                 */
                horizontal_scroll.addView(vertical_scroll);

                /*
                 * at last add this horizontal scroll in side parent which will
                 * hold the multidirectional scroll
                 */
                parent.setTag(getScrollHandler());
                parent.addView(horizontal_scroll);

                // vertical_scroll.setId(id)

                panHandler.setVerticalScroll(vertical_scroll);
                panHandler.setHandlerTag(getScrollHandler());
                panHandler.setPanoSpeed(Integer.parseInt(getScrollSpeed()));

                storePanoHandler.add(panHandler);
                int size = storePanoHandler.size();
                System.out.println("Vertical Scroll objec size=" + size);

            }
            System.out.println("TAg= " + parent.getTag());
            String scdir = getScrollDirection();
            System.out.println("Scroll Directoion= " + scdir);

            scrollid++;

            if (getScrollDirection().equalsIgnoreCase("Y")) {
                vertical_scroll.setScrollViewListener(new CustomScrollLisner() {

                    @Override
                    public void onScrollChanged(
                            CustomHorizontalObserveScroll scrollView, int x,
                            int y, int oldx, int oldy) {
                    }

                    @Override
                    public void onScrollChanged(
                            CustomVerticalObserveScroll scrollView, int x,
                            int y, int oldx, int oldy) {
                        if (scrollView == storePanoHandler.get(getTOuchId())
                                .getVerticalScroll()) {

                            for (int i = 0; i &lt; storePanoHandler.size(); i++) {

                                storePanoHandler.get(i).getVerticalScroll()
                                        .scrollTo(x, y);

                                storePanoHandler.get(i).getVerticalScroll().

                                // storePanoHandler.
                                // .get(i)
                                // .getVerticalScroll()
                                // .scrollTo(
                                // x,
                                // oldy
                                // + storePanoHandler.get(
                                // i)
                                // .getPanoSpeed());
                            }

                        }
                    }
                });
            }

            // if (getScrollDirection().equalsIgnoreCase("X")) {
            // vertical_scroll.setScrollViewListener(new CustomScrollLisner() {
            //
            // @Override
            // public void onScrollChanged(
            // CustomHorizontalObserveScroll scrollView, int x,
            // int y, int oldx, int oldy) {
            // // if (scrollView == storePanoHandler.get(getTOuchId())
            // // .getVerticalScroll()) {
            // //
            // // for (int i = 0; i &lt; storePanoHandler.size(); i++) {
            // // storePanoHandler.get(i).getVerticalScroll()
            // // .smoothScrollTo(x, y);
            // //
            // // }
            // // }
            // }
            //
            // @Override
            // public void onScrollChanged(
            // CustomVerticalObserveScroll scrollView, int x,
            // int y, int oldx, int oldy) {
            // }
            // });
            // }

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        /*
         * set touch listeners on vertical and horizontal scrolls it will use to
         * disable the scroll for it's parent like [image or view pager when
         * user interacting with any of custom scroll]
         */
        horizontal_scroll.setOnTouchListener(this);
        vertical_scroll.setOnTouchListener(this);

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        boolean scrollingPanaroma = true;
        // changing token value for getting scroll

        if (v == vertical_scroll || v == horizontal_scroll) {
            /*
             * Disabling the parent control [list, pager] when user interacting
             * with multidirectional scroll
             */
            System.out.println("Pano touch Id= " + vertical_scroll.getId());

            setTouchId(vertical_scroll.getId());

            if (scrollingPanaroma == true) {
                v.getParent().getParent().getParent()
                        .requestDisallowInterceptTouchEvent(true);
            }
            /*
             * enable the parent control [list, pager] when user done with
             * multidirectional scroll
             */
            else {
                v.getParent().getParent().getParent()
                        .requestDisallowInterceptTouchEvent(false);
            }
        }
        return false;

    }
}
</code></pre>

<p>Please help me to solve this out because I am really stucked at this point. Thnaks.</p>
