Problem z RelativeLayout, gdy widoczność widoku to View.GONE

82

Mam RelativeLayoutwięc:

<RelativeLayout>
<TextView1/>
<TextView2/> // <-- View.VISIBLE OR View.GONE
<TextView3/>
<TextView4/>
</RelativeLayout>

Każdy TextViewjest zakotwiczony poniżej poprzedniego za TextViewpomocą android:layout_below.

Problem polega na tym, że TextView2 może tam być lub nie (albo View.VISIBLEalbo View.GONE); jeśli tak View.VISIBLE, to wszystko jest w porządku, ale jeśli tak View.GONE, to TextView3 kończy się renderowaniem na wierzchu TextView1.

Wypróbowałem różne sposoby, aby to naprawić, ale za każdym razem łapie mnie RelativeLayoutzasada „nie można odwołać się do identyfikatora przed jego zdefiniowaniem”.

Mam nadzieję, że brakuje mi tu czegoś oczywistego.

James
źródło
RelativeLayoutma wbudowany mechanizm wyszukiwania najbliższego widoku zakotwiczenia, który nie został usunięty. Sprawdziłem na Gingerbread i jest tam obecny: github.com/aosp-mirror/platform_frameworks_base/blob/…
Miha_x64

Odpowiedzi:

44

Możesz umieścić textview 2 i 3 w LinearLayout i zachować układ liniowy poniżej textview 1.

Karan
źródło
14
Dodanie hierarchii do pliku układu jest zawsze złym pomysłem, zwłaszcza jeśli jest to RelativeLayout. Im więcej dodasz, tym więcej Android utworzy obiekty reprezentujące twój układ. Zamiast tego powinieneś użyć czegoś takiego jak android: layout_alignWithParentIfMissing = "true". Możesz również rozważyć użycie innych układów, na przykład TableLayout.
Francois Dermu
203

Możesz użyć tego tagu:

android:layout_alignWithParentIfMissing="true"

Z dokumentów:

Jeśli ustawiona na true, element nadrzędny będzie używany jako kotwica, gdy nie można znaleźć kotwicy dla układu_doLeftOf, layout_toRightOf itp.

ininprsr
źródło
24
Działa to tylko wtedy, gdy pożądane jest wyrównanie z rodzicem, ale pytanie dotyczyło tego, jak wyrównać z poprzednim widokiem, a nie nadrzędnym.
dimsuz
@dismuz, będzie to bardzo przydatne w zarządzaniu dynamicznymi układami i pozwoli uniknąć niespodzianek w nieprzewidzianych przypadkach narożnych.
ininprsr
11

dlaczego nie zaktualizować belowatrybutu TextView3 podczas aktualizacji widoczności TextView2? (Zakładam, że robisz to w kodzie)

coś jak

TextView tv = (TextView) findViewById(R.id.textview3);
RelativeLayout.LayoutParams lp =
    (RelativeLayout.LayoutParams) tv.getLayoutParams();
lp.addRule(RelativeLayout.BELOW, R.id.textview1);
((TextView) view).setLayoutParams(lp);
slup
źródło
8

Ta odpowiedź nie rozwiązuje konkretnego problemu, ale rozwiązuje podobny, więc miejmy nadzieję, że to komuś pomoże.

Miałem sytuację, w której mój względny układ nie miał odpowiednika Twojego TextView1. Tak więc w mojej sytuacji, jeśli TextView2 zniknął, chciałem, aby TextView3 był wyrównany z górą elementu nadrzędnego. Rozwiązałem to dodając do TextView3 atrybut android: layout_alignWithParentIfMissing = "true". Zobacz http://developer.android.com/resources/articles/layout-tricks-efficiency.html .

Niestety nie widzę sposobu na określenie alternatywnej kotwicy wyrównania, chyba że jest to element nadrzędny.

Samuel Yang
źródło
7

Zapomnij o INVISIBLElub GONE, użyj tego zamiast tego:

RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();

params.height = 0;

params.setMargins(0,0,0,0);

view.setLayoutParams(params);
user925799
źródło
4

możesz to zrobić

<RelativeLayout>
<TextView1/>
<FrameLayout>
  <TextView2/>  // <-- View.VISIBLE OR View.GONE
</FrameLayout>
<TextView3/>
<TextView4/>
</RelativeLayout>

niech TextView3 poniżej tego FrameLayout, który nie ma tła, więc jeśli TextView2 zniknął, nie zajmuje miejsca.

Alittle927
źródło
1

umieść wszystkie textViews w LinearLayout z orientacją pionową.

<LinearLayout>
<TextView/>
<TextView/>
<TextView/>
<TextView/>
<TextView/>
<TextView/>
</LinearLayout>
Ashwini
źródło
-3

Prostym sposobem na to jest granie z alfa 0/1. a także wyłącz onClickListener, jeśli taki istnieje

Taldroid
źródło
Dzięki temu niepotrzebna przestrzeń zostanie zajęta.
Henrique Monte