2

I have a Fragment that contains a RecyclerView. Within that Fragment, I load some data from a database, populate the RecyclerView with it and then want to scroll to a certain position in that RecyclerView.

To perform the scrolling on the UI thread after loading the data, I wanted to use a handler:

public class MyFragment extends Fragment {
    private RecyclerView mRecyclerView;
    private mHandler Handler = new Handler();

    //....

    private void onDataAvailable() {
        // ...
        int scrollPosition = getScrollPosition();
        mHandler.post(new Runnable() {
            public void run() {
                mRecyclerView.smoothScrollToPosition(scrollPosition);
            }
        });

    }
}

However, it never scrolls down.

When I use runOnUiThread, everything works:

public class MyFragment extends Fragment {
    private RecyclerView mRecyclerView;

    //....

    private void onDataAvailable() {
        // ...
        int scrollPosition = getScrollPosition();
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                mRecyclerView.smoothScrollToPosition(scrollPosition);
            }
        });

    }
}

No matter if I instantiate mHandler as new Handler() or as new Handler(Looper.getMainLooper()), it doesn't work.

My understanding was that new Handler(Looper.getMainLooper()) would allow me to execute tasks on the UI thread and should have the same effect as runOnUiThread. What's wrong in my thinking?

UPDATE

For test purposes, I am calling onDataAvailable from the end of my onCreateView function and with mock data loaded. Same effect: With my own handler, it fails to scroll. With runOnUiThread, it works perfectly.

Even more interestingly, I printed the thread ID from outside the runnable for both the handler and runOnUiThread. Both times, the code is run on Thread 1, no difference.

UPDATE 2

Everything works if I use mRecyclerView.scrollToPosition rather than smoothScrollToPosition. Any idea what that could be?

fjc
  • 5,590
  • 17
  • 36
  • If you look at sources they are exceptionally same thing. `runOnUiThread` performs exact same thing with `Handler`. Not sure what may cause that. – azizbekian Feb 07 '17 at 13:14
  • use postDelayed it's work. i dont know why... but its work mHandler.postDelayed(new Runnable() { public void run() { mRecyclerView.smoothScrollToPosition(scrollPosition); } },1); – 배준모 Feb 07 '17 at 13:16
  • 1
    You should show when onDataAvailable is called. Handler always post to an event queue. runOnUiThread might execure immediately. – daemmie Feb 07 '17 at 13:16
  • `postDelayed` doesn't make any difference. I'll add some information how onDataAvailable is called. – fjc Feb 07 '17 at 13:24
  • I have the same problem with runOnUiThread and Handler.post methods, but I execute very simple code - change view's visibility. And I don't know why runOnUiThread works and Handler.post doesn't work. Is there any explanations? – ilyamuromets Jul 26 '18 at 13:11

0 Answers0