为什么 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)
中提供了详细信息
我发现 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)
中提供了详细信息