0

我有一些依赖滚动视图的方法(当我滚动一个视图时,其他视图也会滚动)。我能够正确地做到这一点,但现在我想管理滚动方式的速度(当我滚动我的scrollview1时,scrollview2应该滚动+10,scrollview3应该滚动+20或任何速度)对于其他(scrollview2和scrollview3)相同还。

我检查有一个名为scrollview.scrollto(x,y)的方法。用于管理滚动,但是当我增加 scollto(x, y+scrollviews(i).getSpeed()) 时,它给了我 stackOverflow 异常。

我附上了我的代码,请查看这个并给我一些建议如何解决这个问题。

我的自定义 scrollView 类是:

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)
                && 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) > Math.abs(distanceX)) {
                return true;
            }
            if (Math.abs(distanceX) > Math.abs(distanceY)) {
                return true;
            }
            return false;
        }
    }

}

我用来制作依赖于滚动的滚动视图的这段代码。

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<RelativePanoHandler> storePanoHandler = new ArrayList<RelativePanoHandler>();

    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 > (getLocation().getWidth())
                    || height > (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 > 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 < 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 < 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;

    }
}

请帮我解决这个问题,因为我真的被困在这一点上。谢谢。

4

2 回答 2

0

这是一种方法,对我来说效果很好:

      new CountDownTimer(2000, 20) { 
    public void onTick(long millisUntilFinished) { 
        hv.scrollTo((int) (2000 - millisUntilFinished), 0); 
    } 
    public void onFinish() { 
    } 
 }.start();

所以这里水平滚动视图(hv)在两秒内从位置 0 移动到 2000 或者如果小于 2000px 则移动到视图的末尾。易于调整...

编辑 :

子类Horizo​​ntalScrollView,使用反射来访问Horizo​​ntalScrollView中的私有字段mScroller。当然,如果底层类更改字段名称,这将中断,它默认返回原始滚动实现。

调用 myScroller.startScroll(scrollX, getScrollY(), dx, 0, 500); 改变滚动速度。

       private OverScroller myScroller;     
         private void init()
       {
         try
           {
         Class parent = this.getClass();
        do
          {
        parent = parent.getSuperclass();
       } while (!parent.getName().equals("android.widget.HorizontalScrollView"));
    Log.i("Scroller", "class: " + parent.getName());
    Field field = parent.getDeclaredField("mScroller");
    field.setAccessible(true);
    myScroller = (OverScroller) field.get(this);
    } catch (NoSuchFieldException e)
    {
    e.printStackTrace();
   } catch (IllegalArgumentException e)
   {
    e.printStackTrace();
   } catch (IllegalAccessException e)
   {
    e.printStackTrace();
   }
  }
     public void customSmoothScrollBy(int dx, int dy)
      {
         if (myScroller == null)
        {
    smoothScrollBy(dx, dy);
    return;
  }
        if (getChildCount() == 0)
         return;
final int width = getWidth() - getPaddingRight() - getPaddingLeft();
final int right = getChildAt(0).getWidth();
final int maxX = Math.max(0, right - width);
final int scrollX = getScrollX();
dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
myScroller.startScroll(scrollX, getScrollY(), dx, 0, 500);
invalidate();
  }
    public void customSmoothScrollTo(int x, int y)
   {
    customSmoothScrollBy(x - getScrollX(), y - getScrollY());
  }
于 2013-05-23T06:51:55.157 回答
0

这是我用来以编程方式减慢 ScrollView 滚动速度的代码,

 ObjectAnimator anim = ObjectAnimator.ofInt(mScrollView, "scrollY", mScrollView.getBottom());                               
 anim.setDuration(9000);                     
 anim.start();

mScrollView - 你的 ScrollView

mScrollView = (ScrollView) findViewById(R.id.scrollView1);

anima.setDuration(int Value) - 值越大,滚动越慢 我在 Switch Button OnCheckedChangedListener 中使用了代码块。

于 2014-12-18T08:37:24.463 回答