OnGlobalLayoutListener: 弃用和兼容性

我必须使用一个 OnGlobalLayoutListener对象,然后删除侦听器,我有一个问题与不推荐的方法,我用以下代码解决。

protected void onCreate(Bundle savedInstanceState) {
final LinearLayout llTotal = (LinearLayout) findViewById(R.id.mmc_ll);
ViewTreeObserver vto = llTotal.getViewTreeObserver();
if(vto.isAlive()){
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//
// mycode
//
if (Build.VERSION.SDK_INT<16) {
removeLayoutListenerPre16(llTotal.getViewTreeObserver(),this);
} else {
removeLayoutListenerPost16(llTotal.getViewTreeObserver(), this);
}
}
});
}
super.onCreate(savedInstanceState);
}


@SuppressWarnings("deprecation")
private void removeLayoutListenerPre16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
observer.removeGlobalOnLayoutListener(listener);
}


@TargetApi(16)
private void removeLayoutListenerPost16(ViewTreeObserver observer, OnGlobalLayoutListener listener){
observer.removeOnGlobalLayoutListener(listener);
}

是否正确? 有更好的方法来处理兼容性?

使用 API 10在模拟器中运行代码,LogCat 中有以下警告

04-24 09:30:12.565: I/dalvikvm(471): Could not find method android.view.ViewTreeObserver.removeOnGlobalLayoutListener, referenced from method com.my.project.ActivityHome.removeLayoutListenerPost16
04-24 09:30:12.565: W/dalvikvm(471): VFY: unable to resolve virtual method 2950: Landroid/view/ViewTreeObserver;.removeOnGlobalLayoutListener (Landroid/view/ViewTreeObserver$OnGlobalLayoutListener;)V

我可以忽略他们的,我必须在某种程度上修复?

46809 次浏览

我在我的项目中使用了这个:

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
if (Build.VERSION.SDK_INT < 16) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}

看起来和你的很像。 在不同的设备上测试(4.2.2 & 2.3.3) ,它运行良好。 似乎这是唯一的办法... ... 如果你还发现了什么,我想知道。 祝你好运

2020年编辑 这种方法非常非常过时。我希望您将代码移到了 Kotlin。 现在我们可以在使用 ktx 库时使用 doOnPreDraw 函数。 Https://developer.android.com/reference/kotlin/androidx/core/View/package-summary# (android.View. View) . doonpreDraw (kotlin.Function1)

当然,检查 Android 版本并调用正确的方法要谨慎得多,但是如果你看一下 Android 源代码,你会发现一些有趣的东西:

 @Deprecated
public void removeGlobalOnLayoutListener(OnGlobalLayoutListener victim) {
removeOnGlobalLayoutListener(victim);
}

这段代码是从 API 18上剪下来的

我认为正确的方法是使用 Build.VERSION.SDK_INTBuild.VERSION_CODES:

public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener){
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
} else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}

根据 医生:

此方法在 API 级别16中不推荐使用。改为使用 # RemoveOnGlobalLayoutListener

非常有效。

    mView.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
//noinspection deprecation
mView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
//
// mycode
//
}
});