How to stop automatic scrolling when it reaches the bottom?

I implemented a very slow automatic scrolling of text in 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 } }; 

I can start and stop it simply by clicking on the 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; } } 

I also use NestedScrollView.setOnScrollChangeLisener to determine if the scroll has reached down. And then I use the same method as in my onClick: timerHandler.removeCallbacks (timerRunnable). I see in the magazines that this method has been called, but it has no effect! If I then scroll, autoscrolling continues again. Here is my 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); } } }); 

So, the question is, why does the removeCallbacks call not work in this situation (while it works in onClick) and how to stop the runnable from executing after the scroll reaches the bottom?

0
source share
2 answers

According to the documentation for the Handler.removeCallbacks method , it only deletes message waiting messages. Call the following method:

  handler.removeCallbacksAndMessages(null); 

to delete all messages and prevent further calls.

+1
source

onScrollChange calls immediately after smoothScrollBy (), and it deletes any Callback, but postDelayed () comes after that and makes all onScrollChange work pointless. So the solution is:

 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 } }; 
0
source

Source: https://habr.com/ru/post/988154/


All Articles