Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why ViewTreeObserver > OnScrollChangedListener not called on Android 2.x if it set in onCreate()?

I discovered that OnScrollChangedListener on Android 2.x won't be ever fired if it was added before the first time layout draw. For example, when you add a scroll listener in methods like onCreate/onResume/onAttachedToWindow:

public class MainActivity extends AppCompatActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View myView = findViewById(R.id.MyView);

        System.out.println(myView.getViewTreeObserver().isAlive()); // true

        myView.getViewTreeObserver().addOnScrollChangedListener(new OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
                // will never fire
            }
        });
    }
}

So, anybody knows the reason of this problem?


PS: Seems like the problem sometime happens on API<=15 (Android 4.0.3)

like image 275
Oleg Cherr Avatar asked Sep 27 '22 16:09

Oleg Cherr


1 Answers

So, it seems like a bug. And here is a simple workaround:

To make OnScrollChangedListener work on old devices (apparently API<=15), you should add it either in onWindowFocusChanged(true), or after the layout is measured (use GlobalLayoutListener).

And don't to forget to create a flag like isScrollListenerAdded to avoid repeated listener attaching.

Something like this:

myView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (!isScrollListenerAdded) {
            isScrollListenerAdded = true;
            // add OnScrollChangedListener here
        }
    }
});

Details are available in this blog post about OnScrollChangedListener (Rus; Kotlin)

like image 127
Oleg Cherr Avatar answered Oct 13 '22 00:10

Oleg Cherr