2012-10-13 17 views
7

Tworzę siatkę, która wyświetla wartości, które zmieniają się bardzo często. Z tego powodu korzystam z TextView, który autorejestruje się, gdy zmienia się jego zawartość (Auto Scale TextView Text to Fit within Bounds). Zmiany rozmiaru odbywa, ale widok nie układ prawidłowoUkład widok po zmianie rozmiaru

layout after resize

Chodzi o to, kiedy zbadać aktywność z HierarchyViewer wyświetlacze układu, jak chcę.

layout after hierarchyviewer

Domyślam się, że HierarchyViewer wywołuje requestLayout() lub unieważnić() na widoku, ale próbowałem to bez powodzenia. Ten kod jest wywoływany w głównym działaniu bez żadnego efektu.

new Handler().postDelayed(new Runnable() {    
      @Override 
      public void run() { 
       getWindow().getDecorView().requestLayout(); 
       getWindow().getDecorView().invalidate(); 
      } 
      }, 5000); 

Próbowałem również unieważnić widok po zmianie rozmiaru.

W TextView ustawiono grawitację na Środek, a jeśli nie ma zmiany rozmiaru, wygląda to dobrze.

Wszelkie wskazówki będą mile widziane, z góry dzięki!

+0

Czy próbowałeś zażądać układu w widoku rodzica zamiast widoku dekoracyjnego? – DeeV

+0

Czy widok dekoracji nie jest węzłem nadrzędnym drzewa widoku? Czytałem, że żądanie układu w widoku powoduje, że wszystkie jego dzieci żądają układu. W każdym razie, powiedziałbym, że próbowałem tego, ponieważ próbowałem wielu rzeczy, ale odpowiem, kiedy spróbuję twoich sugestii. Cytowanie dokumentów requestLayout na view.View, "Zadzwoń, gdy coś się zmieniło, co unieważniło układ tego widoku. Zaplanuje to przejście układu drzewa widoku." – Maragues

+0

To robi, ale nie widzę niczego złego w twoim kodzie. requestLayout() układa widok nadrzędny i jest to element potomny, ale nazwałem go tylko widokami bezpośrednio sterowanymi przez moją aplikację, więc jest to tylko myśl. – DeeV

Odpowiedz

2

Rozwiązałem go nadrzędnymi onLayout w jednym z rodzica TextView i stosując Handler utworzony w konstruktorze

public class CellView extends LinearLayout{ 
    public CellView(Context context) { 
    super(context); 

    mHandler = new Handler(); 

    View.inflate(context, R.layout.cellview, this); 
    } 

@Override 
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 
    if(changed){ 
     mHandler.post(new Runnable() {   
     @Override 
     public void run() { 
      requestLayout(); 
     } 
     }); 
    } 

    super.onLayout(changed, left, top, right, bottom); 
    } 

Próbowałem nazywając requestLayout wewnątrz TextView za onLayout, pomimo, że nie działa, jestem nie pewny dlaczego. Możliwe, że wartość została zaktualizowana za pomocą obserwatora, ale odbiornik onTextChanged powinien się pojawić w wątku interfejsu użytkownika. Mam nadzieję, że służy komuś innemu

0

Prawdopodobnie musisz uruchomić kod czasowy w wątku UI, używając runOnUiThread, jak wyjaśniono here.

+0

Zakładając, że tworzy on Handler w wątku UI, działa w wątku UI. – DeeV

+0

Sprawdzę to później (teraz nie pracuję nad tym). Powiedziałbym, że uruchomienie tego kodu spoza wątku UI spowodowałoby wyjątek, ale mógłbym utworzyć Handler poza wątkiem UI. Dzięki dwóm (Narcís i DeeV) za pomysł – Maragues

2

Sposób, w jaki działa requestLayout(), polega na tym, że po wywołaniu widoku zaplanuje przekazanie układu dla siebie i wszystkich jego elementów potomnych. Jest to pożądane, gdy widok jest przesuwany lub zmieniany, do marginesów, dopełnienia lub zmian treści.

Dokumentacja metody getDecorView() nie jest bardzo jasna co dokładnie daje. Jednak za dokumentacji na website:

Zauważ, że wywołanie tej funkcji po raz pierwszy „Zamki w” różnych cech okiennych, jak to opisano w setContentView (Widok android.view.ViewGroup.LayoutParams).

To pozostawia mi do myślenia, że ​​jest coś specjalnego w widoku, który pobiera getDecorView(). Prawdopodobnie robisz to, aby układ widoku był trwały, a więc nigdy się nie zmienia po przejściu przez requestLayout().

This is apparently the proper way to get the root view of your entire activity.

Jednakże, ze względu na efektywność, polecam dzwoniąc requestLayout() na najniższym dziecka to możliwe. Tak jak powiedziałem wcześniej, planuje ona przekazanie layoutu na widok i to jest dziecko. Jeśli wykonasz rzutowanie układu w najwyższym widoku, zawsze przebudowujesz wszystko, co obejmuje widoki, które pozostają w miejscu.

+0

jesteś, dzięki za poświęcony czas i miłe badania na requestLayout, jednak zachowam moją wybraną odpowiedź, ponieważ rozwiązuje ona mój konkretny problem. Jeśli w przyszłości użytkownicy będą głosować na Ciebie, przyznam ci to – Maragues

Powiązane problemy