0

我在使用 Scroller 以编程方式滚动 ScrollView 时遇到问题,因此到目前为止还没有涉及到触摸手势。只要来自传感器的数据在一定范围内,我想以一定的速度向下滚动 ScrollView。所以基本上我想在数据第一次进入有效范围时开始滚动,然后不干扰滚动过程,直到数据再次超出范围。我不想将 onSensorChanged 直接连接到 scrollBy() ,因为它可能无法在其他设备上正常工作。这是我到目前为止所得到的:

在我的 onCreate 中:

tx = new TextView(ShowLyrics.this);
mainscrollarea = (ScrollView) findViewById (R.id.mainscrollarea);
scroller = new Scroller(getApplicationContext(), new LinearInterpolator());
tx.setScroller(scroller);

在我的 onSensorChanged 中:

if(integratedAngle - scrollTolerance > pointzero){ //this is checking for the data range and works so far
    if(!scrollingDown){
        scrollText("down");
        }
    }

和 scrollText 函数:

void scrollText(String direction){

    if(direction.matches("down")){
        scrollingUp = false;
        scrollingDown = true;           
        scroller.forceFinished(true);
        int currY = mainscrollarea.getScrollY();
        int endY = tx.getHeight();
        int distance = endY - currY;            
        scroller.startScroll(0, currY, 0, -distance, 5000);

    }

    if(direction.matches("up")){
    //nothing yet   
    }
}

所以现在我已经硬编码了 5 秒来向下滚动,但没有任何反应。onSensorChanged 中 Scroller 的 getCurrY 的 Log.d() 只吐出 0。如果有人能指出我正确的方向,我将不胜感激。

4

1 回答 1

0

我有点像你一样自动滚动。除了我依赖用户输入(当用户用手指靠近屏幕边缘时,我开始以特定速度滚动)。

我使用了一个可运行的对象,它的作用与滚动条的作用相同。

private final DragScroller mDragScroller;

/** inner class */
private class DragScroller implements Runnable {
    private SCROLL_DIRECTION mDirection;
    private boolean          mIsFinished = true;

    DragScroller(Context context) {
    }

    void start(SCROLL_DIRECTION direction) {
        mState = STATE.DRAG_SCROLL;
        mIsFinished = false;
        mDirection = direction;
        post(this);
    }

    @Override
    public void run() {
        if (mIsFinished) {
            return;
        }
        if (mDirection.equals(SCROLL_DIRECTION.UP)) {
            // check if the touch is still in the correct area...
            if (!isOverThreshold(0, mTempY, mDragScrollThreshold)) {
                scrollTo(0, ensureScrollBoundaries(getScrollY() - mDragScrollSpeed));
                post(this);
            } else {
                forceFinish();
            }
        } else {
            // check if the touch is still in the correct area...
            if (!isOverThreshold(getHeight(), mTempY, mDragScrollThreshold)) {
                scrollTo(0, ensureScrollBoundaries(getScrollY() + mDragScrollSpeed));
                post(this);
            } else {
                forceFinish();
            }
        }
    }

    public boolean isFinished() {
        return mIsFinished;
    }

    public void forceFinish() {
        mIsFinished = true;
    }
}

它只是由以下方式启动:mDragScroller.start(SCROLL_DIRECTION.UP);并且可以通过以下方式停止mDragScroller.forceFinish();

编辑

根据您的评论,您希望将持续时间用于速度。这是有问题的,因为最终的滚动速度取决于您在给定时间内必须滚动的距离。简短的数学示例:在 1 分钟内滚动 600 像素意味着您每秒滚动 10 像素,这还不错(取决于您滚动的内容、文本或图像......)但如果您靠近边缘并且您只需要滚动 60 像素,则结果速度取决于给定的 1 分钟持续时间,这意味着每秒非常慢 1 像素。

鉴于该示例,您的滚动速度不应基于总持续时间,而是基于每秒像素。

是的,无需使用 Scroller 进行编程滚动。只是runnable会调用自己直到它应该停止并且速度可以调整到你需要的任何东西......

于 2013-04-14T10:41:25.590 回答