Jak mogę zmienić pozycję widoku za pomocą kodu? Jak zmiana jego pozycji X, Y. Czy to możliwe?
Jak mogę zmienić pozycję widoku za pomocą kodu? Jak zmiana jego pozycji X, Y. Czy to możliwe?
Odpowiedzi:
W przypadku wszystkiego poniżej Honeycomb (poziom API 11) będziesz musiał użyć setLayoutParams(...)
.
Jeśli można ograniczyć wsparcie Honeycomb i nawet można użyć setX(...)
, setY(...)
, setLeft(...)
, setTop(...)
, itd.
Tak, możesz dynamicznie ustawiać pozycję widoku w systemie Android. Podobnie masz ImageView
in LinearLayout
w pliku xml, więc możesz ustawić jego pozycję za pomocą LayoutParams
.Ale upewnij się, że robisz to LayoutParams
zgodnie z układem wykonanym w pliku xml. Są różne w LayoutParams
zależności od przyjętego układu.
Oto kod do ustawienia:
LayoutParams layoutParams=new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);
Mam nadzieję, że ustawienie pozycji będzie pomocne.
Istnieją już różne prawidłowe odpowiedzi, ale żadna z nich nie wydaje się właściwie sugerować, której metody należy użyć w danym przypadku, z wyjątkiem odpowiednich ograniczeń na poziomie interfejsu API:
Jeśli możesz poczekać na cykl układu, a nadrzędna grupa widoków obsługuje MarginLayoutParams
(lub podklasę), ustaw marginLeft
/ marginTop
odpowiednio.
Jeśli potrzebujesz natychmiast i trwale zmienić pozycję (np. Dla kotwicy PopupMenu), dodatkowo wywołaj layout(l, t, r, b)
z tymi samymi współrzędnymi. To wyklucza to, co system układu potwierdzi później.
W przypadku natychmiastowych (tymczasowych) zmian (takich jak animacje) użyj zamiast tego setX()
/ setY()
. W przypadkach, gdy rozmiar nadrzędny nie zależy od WRAP_CHILDREN, użycie setX()
/ setY()
wyłączność może być w porządku .
Nigdy nie używaj setLeft()
/ setRight()
/ setBottom()
/ setTop()
, patrz poniżej.
tło : pola mLeft
/ mTop
/ mBottom
/ mRight
są wypełniane z odpowiednich parametrów LayoutParams w układzie (). Układ jest wywoływany niejawnie i asynchronicznie przez system układu widoku systemu Android. Dlatego ustawienie MarginLayoutParams
wydaje się być najbezpieczniejszym i najczystszym sposobem na ustawienie pozycji na stałe. Jednak asynchroniczne opóźnienie układu może stanowić problem w niektórych przypadkach, np. Podczas korzystania z widoku do renderowania kursora, i powinno zostać ponownie umieszczone i służyć jako kotwica PopupMenu w tym samym czasie. W tym przypadku dzwonienie layout()
działało dobrze.
Problemy z setLeft()
i setTop()
to:
Samo dzwonienie do nich nie wystarczy - trzeba też zadzwonić setRight()
i setBottom()
unikać rozciągania lub zawężania widoku.
Implementacja tych metod wygląda na stosunkowo złożoną (= wykonanie pewnej pracy w celu uwzględnienia zmian rozmiaru widoku spowodowanych przez każdą z nich)
Wydaje się, że powodują dziwne problemy z polami wejściowymi: miękka klawiatura numeryczna EditText czasami nie zezwala na cyfry
setX()
i setY()
działają poza układem układu, a odpowiednie wartości są traktowane jako dodatkowe odsunięcie do wartości w lewo / w górę / w dół / w prawo określonych przez system układu, odpowiednio przesuwając widok. Wydaje się, że zostały dodane do animacji (gdzie wymagany jest natychmiastowy efekt bez przechodzenia przez cykl układu).
marginLeft
można ustawić za pomocą setLayoutParams
a, new FrameLayout.LayoutParams(width, height)
na którym ustawionomarginLeft
Istnieje biblioteka o nazwie NineOldAndroids , która umożliwia korzystanie z biblioteki animacji Honeycomb aż do wersji pierwszej.
Oznacza to, że możesz zdefiniować left, right, translationX / Y z nieco innym interfejsem.
Oto jak to działa:
ViewHelper.setTranslationX(view, 50f);
Wystarczy użyć statycznych metod z klasy ViewHelper, przekazać widok i jakąkolwiek wartość, na jaką chcesz go ustawić.
Polecam używanie setTranslationX
i setTranslationY
. Sam dopiero zaczynam, ale wydaje mi się, że to najbezpieczniejszy i preferowany sposób przesuwania widoku. Myślę, że zależy to w dużej mierze od tego, co dokładnie próbujesz zrobić, ale to działa dobrze w przypadku animacji 2D.
Jeśli używasz HoneyComb Sdk (poziom interfejsu API 11), możesz spróbować użyć następujących metod.
view.setX(float x);
Parametr x to wizualna pozycja x tego widoku.
view.setY(float y);
Parametr y jest wizualną pozycją y tego widoku.
Mam nadzieję, że okaże się pomocny. :)
Aby uzyskać obsługę wszystkich poziomów API, możesz go używać w następujący sposób:
ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);
Ustaw lewą pozycję tego widoku względem jego rodzica:
view.setLeft(int leftPosition);
Ustaw właściwą pozycję tego widoku względem jego elementu nadrzędnego:
view.setRight(int rightPosition);
Ustaw najwyższą pozycję tego widoku względem jego elementu nadrzędnego:
view.setTop(int topPosition);
Ustaw dolną pozycję tego widoku względem jego elementu nadrzędnego:
view.setBottom(int bottomPositon);
Powyższe metody służą do ustawiania pozycji widoku związanego z jego rodzicem.
Użyj LayoutParams. Jeśli używasz LinearLayout, musisz zaimportować android.widget.LinearLayout.LayoutParams, w przeciwnym razie zaimportuj odpowiednią wersję LayoutParams dla używanego układu lub spowoduje to wyjątek ClassCast , a następnie:
LayoutParams layoutParams = new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);
Uwaga: Zauważ, że możesz użyć również imageView.setLeft (int dim), ALE TO NIE BĘDZIE ustawiało pozycji komponentu, ustawi tylko pozycję lewej krawędzi komponentu, reszta pozostanie w tej samej pozycji .
Odkryłem, że @Stefan Haustein jest bardzo blisko mojego doświadczenia, ale nie jestem pewien w 100%. Moja sugestia to:
setLeft()
/ setRight()
/ setBottom()
/ setTop()
czasami nie działa.setX()
/setY()
zamiast. (Możesz chcieć wyszukiwać bardziej w różnicy setLeft()
isetX()
)Jedną rzeczą, o której należy pamiętać przy pozycjonowaniu, jest to, że każdy widok ma indeks względem swojego widoku nadrzędnego. Więc jeśli masz układ liniowy z trzema podglądami podrzędnymi, każdy z podglądów częściowych będzie miał indeks: 0, 1, 2 w powyższym przypadku.
Pozwala to na dodanie widoku do ostatniej pozycji (lub końca) w widoku nadrzędnym, wykonując coś takiego:
int childCount = parent.getChildCount();
parentView.addView(newView, childCount);
Alternatywnie możesz zastąpić widok, używając czegoś podobnego do następującego:
int childIndex = parentView.indexOfChild(childView);
childView.setVisibility(View.GONE);
parentView.addView(newView, childIndex);
sets the top position of this view relative to its parent. This method is meant to be called by the layout system and should not generally be called otherwise, because the property may be changed at any time by the layout.
- więc może to nie taki dobry pomysł;)