Android webview Scrolling表现得很奇怪

时间:2014-09-09 07:18:25

标签: android

在我的应用程序中,我有一个webview,允许用户通过滑动手势水平滚动。

我使用objectanimator为滚动设置动画,但即使使用简单的scrollTo(),问题仍然存在。

问题:当我到某个位置时使用:scrollTo(500,0);它经常会向一侧跳过一定数量的像素,就像100px的抖动一样。

如果我在第一次滑动完成后继续向右滑动,则错误不会发生并且它会按预期运行,但是当我停止滑动最后一次滑动的那一刻以随机抖动结束。

代码非常简单,基本上是:myView.scrollTo(X,Y)。我完全不知道为什么会这样。谁有类似的经历?

更新从touchevent中输入代码,一些已经过时的内容是繁琐的试错。

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(final MotionEvent event) {

    if(swipeable && !animationRunning){
        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                swipeStartPosition = event.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                // Nothing here, move along.
                break;
            case MotionEvent.ACTION_UP:

                float swipeDistance = Math.abs(event.getX() - swipeStartPosition);

                // Check if event is click or swipe.
                // A swipe is hardcoded to a distance of 50px.
                if (swipeDistance > 50) {
                    // Swipe.

                    if (event.getX() > swipeStartPosition) {
                        // Right swipe (previous).
                        // Don't swipe if you're on the first page.
                        if (targetPage == 0) {
                            Toast.makeText(getContext(), "No sections that way, try the other way.", Toast.LENGTH_SHORT).show();
                        } else {
                            prevPage = targetPage;
                            targetPage--;

                            //inform main activity about pagechange to update UI
                            mMainActivity.setTargetPage(prevPage, targetPage);

                            /*
                            mWebView.postDelayed( new Runnable () {
                                @Override
                                public void run() {
                                    mWebView.scrollTo(2560, 0);
                                }
                            }, 3000);
                            */

                            //scrollTo(2560, 0);//targetPage * pageWidth, 0);

                            ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);

                            objectAnimator.addListener(new AnimatorListener() {

                                @Override
                                public void onAnimationStart(Animator arg0) {
                                    // TODO Auto-generated method stub

                                }

                                @Override
                                public void onAnimationRepeat(Animator arg0) {
                                    // TODO Auto-generated method stub

                                }

                                @Override
                                public void onAnimationEnd(Animator arg0) {
                                    // TODO Auto-generated method stub
                                    animationRunning = false;

                                }

                                @Override
                                public void onAnimationCancel(Animator arg0) {
                                    // TODO Auto-generated method stub

                                }
                            });
                            objectAnimator.start();

                        }
                    } else {
                        // Left swipe (next).

                        if (computeHorizontalScrollRange() <= (computeHorizontalScrollOffset() + computeHorizontalScrollExtent())) {
                            Toast.makeText(getContext(), "No sections that way, try the other way.", Toast.LENGTH_SHORT).show();
                        } else {
                            prevPage = targetPage;
                            targetPage++;

                            mMainActivity.setTargetPage(prevPage, targetPage);

                            /*
                            mWebView.postDelayed( new Runnable () {
                                @Override
                                public void run() {
                                    mWebView.scrollTo(5120, 0);
                                }
                            }, 3000);
                            */
                            //scrollTo(5120, 0); //targetPage * pageWidth, 0);

                            ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);

                            objectAnimator.addListener(new AnimatorListener() {

                                @Override
                                public void onAnimationStart(Animator arg0) {
                                    // TODO Auto-generated method stub

                                }

                                @Override
                                public void onAnimationRepeat(Animator arg0) {
                                    // TODO Auto-generated method stub

                                }

                                @Override
                                public void onAnimationEnd(Animator arg0) {
                                    // TODO Auto-generated method stub
                                    animationRunning = false;
                                }

                                @Override
                                public void onAnimationCancel(Animator arg0) {
                                    // TODO Auto-generated method stub

                                }
                            });

                            objectAnimator.start();

                        }
                    }

                } else {
                    // Click.
                    // Do nothing here.
                }

//                int pageWidth = getWidth();
//               
//                int targetPage = (int)Math.round(  (pos + event.getX()) / (float)pageWidth  );
//                
//                
//                scrollTo(targetPage * pageWidth, 0);

                break;  
        }
    }

    return super.onTouchEvent(event);
}

此外,正在发生的位移似乎与最初的touchevent本身绑定,而不是滚动。如果我执行以下操作并延迟3秒,我会看到在触摸事件后短时间内再次发生位移,但是当scrollTo()在3秒后触发时它会实际跳转到正确的位置:

mWebView.postDelayed( new Runnable () {
                            @Override
                            public void run() {
                                mWebView.scrollTo(2560, 0);
                            }
                        }, 3000);

这一切都令人费解......

1 个答案:

答案 0 :(得分:0)

事实证明,在原始代码的某处,有些事搞砸了。 这是一个非常不同,更简单的例子,它完美地运作。

float x1,x2;
float y1,y2;

@Override
public boolean onTouchEvent(MotionEvent event) {
    // TODO Auto-generated method stub

    switch(event.getAction())
    {
        case MotionEvent.ACTION_DOWN:
            x1 = event.getX();
            y1 = event.getY();
            break;

        case MotionEvent.ACTION_UP:
            x2 = event.getX();
            y2 = event.getY();

            if(x1 < x2){
                //left to right
                prevPage = targetPage;
                targetPage--;

                Toast.makeText(getContext(), "left to right", Toast.LENGTH_SHORT).show();

                ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);
                objectAnimator.start();
            }
            if(x1 > x2){
                //right to left

                prevPage = targetPage;
                targetPage++;

                Toast.makeText(getContext(), "right to left", Toast.LENGTH_SHORT).show();

                ObjectAnimator objectAnimator = ObjectAnimator.ofInt(this.mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * pageWidth)).setDuration(300);
                objectAnimator.start();
            }
            /*
            ObjectAnimator objectAnimator = ObjectAnimator.ofInt(mWebView, "scrollX", computeHorizontalScrollOffset(), (targetPage * displaymetrics.widthPixels)).setDuration(300);
            objectAnimator.start();
            */
            break;

    }

    return true;
}