2013-04-24 5 views
62

Ich muss ein OnGlobalLayoutListener Objekt verwenden und dann, um den Listener zu entfernen, hatte ich ein Problem mit veralteten Methoden, die ich mit folgendem Code auflösen.OnGlobalLayoutListener: Abwertung und Kompatibilität

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

Ist es richtig? Es gibt eine bessere Möglichkeit, mit Kompatibilität umzugehen?

Ausführen des Codes in Emulator mit API 10 habe ich die folgende Warnung in 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 

Kann ich ignoriere sich von mir in irgendeiner Art und Weise zu beheben habe?

Antwort

126

Ich verwende in meinem Projekt:

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

ähnlich wie bei Ihnen aussieht. Getestet auf verschiedenen Geräten (4.2.2 & 2.3.3) und es läuft perfekt. scheint wie es ist der einzige Weg .... Wenn Sie etwas anderes finden, würde ich es gerne wissen. Glück

+0

Am Anfang habe ich Ihren Code verwendet, aber es einen Fehler geben (Anruf erfordert API-Ebene 16 (Strom min 8): android.view.ViewTreeObserver # removeOnGlobalLayoutListener) und eine Warnung (Die Methode removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener) vom Typ ViewTreeObserver ist veraltet). Mein Code löst diese Probleme, aber geben Sie die LogCat-Warnung – crbin1

+0

Warnung ist in Ordnung. Das liegt daran, dass Sie jar mit einer sdk-Version mit veralteter Funktion für Geräte

+9

@ crbin1 Sie können @TargetApi (Build.VERSION_CODES.JELLY_BEAN) vor der Funktionsdeklaration hinzufügen, wenn Sie diese Warnung/diesen Fehler vermeiden möchten. –

9

natürlich, dass die Android-Version überprüfen und rufen Sie die richtige Methode viel vorsichtiger ist, aber wenn man einen Blick auf die Android-Quellcode nehmen Sie etwas Interessantes sehen:

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

Dieser Code von API 18

36

snipped wurde ich glaube, die richtige Art und Weise Build.VERSION.SDK_INT und Build.VERSION_CODES verwendet:

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

Ich denke, du willst den Listener an 'removeGlobalLayoutListener' anstatt an' this' übergeben –

3

Nach dem docs:

Diese Methode in API-Ebene weiterentwickelt wurde stattdessen 16. Verwendung #removeOnGlobalLayoutListener

Arbeiten wie ein Charme.

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