2016-02-16 13 views
5

Zaten ViewTreeObserver'u sorunsuz kullanıyorum ancak bu durumda onGlobalLayout geri bildirimini alamıyorum.ViewTreeObserver onGlobalLayout öğesinden aramıyor

Bir http API çağrısı gerçekleştirdikten sonra bir görünümün genişliğini aldığımdan, genişlik zaten hesaplanmış gibi görünüyor (API çağrısının aldığı zaman nedeniyle). Her neyse, emin olmak için ViewTreeObserver'a bir dinleyici ekliyorum. Ama bazen geri aramayı alamıyorum (evet, bazen).

Geri aramak için beklemekten kaçınmak için dinleyiciyi eklemeden önce genişliğini kontrol edebilirim, ancak bazen neden geri dönüşü alamadığımı bilmiyorum. viewTreeObserver'un her zaman canlı olduğunu kontrol ettim.

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver(); 

assert viewTreeObserver.isAlive(); 

viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() // Not called sometimes, why? 
    { 
     view.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
     doSomething(view.getWidth()); 
    } 
}); 

ben bu hileyi kullanacaktır Şimdilik:

int width = view.getWidth(); 

if (width > 0) { 
    doSomething(view.getWidth()); 
} else { 
    // use the ViewTreeObserver 
} 

EDIT:

ben bu yardımcı yöntemini yapılan yardım olur ne olmaz

:

/** 
* Runs code on global layout event, useful when we need to do something after the layout is done 
* (like getting the view real measure). The runnable is only called once at most. 
* 
* A typical `shouldRun` function can be `v -> v.getWidth() > 0` since it checks that the view has some width, 
* so we can calculate things depending on that. 
* 
* @param shouldRun receives the `view` and decides if the runnable should run (it is checked when this method is called, and also on global layout). 
* 
* See: http://stackoverflow.com/questions/35443681/viewtreeobserver-doesnt-call-ongloballayout 
*/ 
public static void runOnGlobalLayout(final View view, final Func1<View,Boolean> shouldRun, final Runnable runnable) 
{ 
    if (shouldRun.call(view)) { 
     runnable.run(); 
     return; 
    } 

    final ViewTreeObserver viewTreeObserver = view.getViewTreeObserver(); 

    if (viewTreeObserver.isAlive()) { 
     viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
      @Override 
      public void onGlobalLayout() { 
       if (shouldRun.call(view)) { 
        view.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        runnable.run(); 
       } 
      } 
     }); 
    } 
} 
runOnGlobalLayout(someLayout, v -> v.getWidth() > 0,() -> { 
    int availableWidth = someLayout.getWidth(); 
    // draw things in layout, etc. 
}); 

cevap

4

resmi belgelerine yaklaşık ViewTreeObserver.OnGlobalLayoutListener: örneğin yapabileceği yöntemle 10

geri aramayı

Arayüz tanımı çağrılacak zaman küresel düzen eyalet veya görünümlerin görünürlüğü ağaç değişimlerini görüntüle.

sizin http geri arama (onun subviews ile) görüş son görünürlük değişikliğinden sonra gelirse o size OnGlobalLayoutListener herhangi geri arama almıyorsanız bu normal.

Geri arama alacağınız durum, tüm görüşleriniz oluşturulmadan önce http isteğinizin bittiği durumdur. Bu nedenle, onGlobalLayout numaranızda, görünümlerin çiziminin bitişine atıfta bulunulan bir geri arama alırsınız.

+0

Teşekkürler! Android'e söyleyebilmenin bir yolunu biliyor musunuz: "Hey, bu görüş ölçülen hesaplandığında bana haber verir misiniz?" –

+2

@FerranMaylinch yes: viewWithGlobalListener.requestLayout() –

+2

@FerranMaylinch Ölçüleri manuel olarak yeniden hesaplayacaktır. Bu, onGlobalLayout geri çağrısına girecektir. –

İlgili konular