为什么ViewTreeObserver> OnScrollChangedListener在Android 2.x上没有调用它是否在onCreate()中设置?

Ole*_*err 5 android android-layout android-2.3-gingerbread android-view android-4.0-ice-cream-sandwich

我发现OnScrollChangedListener在Android 2.x上如果在第一次布局绘制之前添加它,就不会被解雇.例如,在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
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

那么,有谁知道这个问题的原因?


PS:似乎问题有时发生在API <= 15(Android 4.0.3)

Ole*_*err 4

所以,这看起来像是一个错误。这是一个简单的解决方法:

OnScrollChangedListener在旧设备(显然 API<=15)上工作,您应该将其添加到 中onWindowFocusChanged(true),或在测量布局之后(使用GlobalLayoutListener)。

并且不要忘记创建一个标志,isScrollListenerAdded以避免重复监听器附加。

像这样的东西:

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

详细信息请参阅这篇有关 OnScrollChangedListener (Rus;Kotlin)的博客文章