2013-04-24 157 views
62

我必须使用一个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 

以下警告我能不理会他们的我必须以某种方式来解决?

回答

126

我在我的项目中使用这样的:

@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)并且运行完美。 似乎是唯一的方法....如果你发现任何其他我想知道它。 好运

+0

在开始的时候我用了你的代码,但它给一个错误(调用API需要16级(当前分钟8):android.view.ViewTreeObserver#removeOnGlobalLayoutListener)和警告(该方法removeGlobalOnLayoutListener(ViewTreeObserver.OnGlobalLayoutListener )从类型ViewTreeObserver被弃用)。我的代码解决了这些问题,但给LogCat警告 – crbin1 2013-04-24 12:09:30

+0

警告是好的。这是因为你正在使用jar版本的某些sdk版本,并为设备 2013-04-24 14:22:34

+9

@ crbin1如果您希望避免看到此警告/错误,您可以在函数声明之前添加@TargetApi(Build.VERSION_CODES.JELLY_BEAN)。 – 2013-07-02 07:53:50

9

当然,入住的Android版本,并调用正确的方法是更加谨慎,但如果你对Android源代码一看就可以看到一些有趣的事情:

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

此代码从API被剪断18

36

我认为正确的方法是使用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); 
      } 
} 
+1

我想你想通过侦听器'removeGlobalLayoutListener'而不是'this' – 2015-12-29 12:44:30

3

按照docs

此方法在API级别16.利用#removeOnGlobalLayoutListener代替

就像一个魅力被弃用。

7
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 
      // 
     } 
    });