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

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

我发现 Android 2.x 上的 OnScrollChangedListener 如果在第一次布局绘制之前添加,则永远不会被触发。例如,当您在 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
            }
        });
    }
}

所以,有人知道这个问题的原因吗?


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

所以,这似乎是一个错误。这是一个简单的解决方法:

要使 OnScrollChangedListener 在旧设备上工作(显然 API<=15),您应该在 onWindowFocusChanged(true) 中添加它,或者在测量布局后添加它(使用 GlobalLayoutListener).

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

像这样:

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

blog post about OnScrollChangedListener(Rus;Kotlin)

中提供了详细信息