当它到达底部时如何停止自动滚动?

时间:2015-10-22 13:06:43

标签: android

我在ScrollView中为歌词文本实现了非常慢的自动滚动:

private Handler timerHandler;
private Runnable timerRunnable;
private boolean isScrolling = false;
private TextView mSongTextTv;

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  ....

 mSongTextTv.setOnClickListener(this);

    // Scroll Hendler
    timerHandler = new Handler();
    timerRunnable = new Runnable() {
        @Override
        public void run() {
            mScrollView.smoothScrollBy(0, 1);         // 1 is how many pixels you want it to scroll vertically by
            timerHandler.postDelayed(this, 40);     // 40 is how many milliseconds you want this thread to run
        }
    };

我可以通过单击TextView:

来启动和停止它
@Override
public void onClick(View v) {
    switch (v.getId()) {
            ...
        case R.id.tv_song:
            if (!isScrolling) {
                timerHandler.postDelayed(timerRunnable, 0);
                isScrolling = true;
                Log.d("song tap", " is running = " + isScrolling);
            } else {
                timerHandler.removeCallbacks(timerRunnable);
                isScrolling = false;
                Log.d("song tap", " is running = " + isScrolling);
            }
        break;
    }
}

我还使用NestedScrollView.setOnScrollChangeLisener来识别滚动是否到达底部。然后我使用与onClick相同的方法:timerHandler.removeCallbacks(timerRunnable)。我可以在日志中看到这个方法被调用但它没有效果!如果我然后再向上滚动继续自动滚动。这是我的onScrollChangeListener:

mScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
        @Override
        public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {                
            View view = mScrollView.getChildAt(mScrollView.getChildCount()-1);
            int diff = (view.getBottom() - (mScrollView.getHeight() + mScrollView.getScrollY()));

            if (diff == 0 && isScrolling) {
                timerHandler.removeCallbacks(timerRunnable);
                isScrolling = false;
                Log.d("song tap", " isScrolling = " + isScrolling);
                Log.d("onScrollChange", "reached bottom, diff = " + diff);
            }
        }
    });

所以问题是为什么对removeCallbacks的调用在这种情况下不起作用(当它在onClick中工作时)以及如何在滚动到达底部后停止执行runnable?

2 个答案:

答案 0 :(得分:1)

根据方法Handler.removeCallbacks的文件 它仅删除待处理的消息。请致电以下方法:

    handler.removeCallbacksAndMessages(null);

删除所有邮件并阻止进一步通话。

答案 1 :(得分:0)

onScrollChange在smoothScrollBy()之后立即调用,它会删除任何回调,但postDelayed()会在此之后执行,并且所有onScrollChange的工作都没有意义。所以解决方案是:

timerRunnable = new Runnable() {
        @Override
        public void run() {
            timerHandler.postDelayed(this, 10);     // 10 is how many milliseconds you want this thread to run
            mScrollView.smoothScrollBy(0, 5);         // 5 is how many pixels you want it to scroll vertically by
        }
    };