W ten , ten i ten wątek starałem się znaleźć odpowiedź, w jaki sposób ustawić marginesy na jednym widoku. Zastanawiałem się jednak, czy nie ma prostszego sposobu. Wyjaśnię, dlaczego wolałbym nie stosować tego podejścia:
Mam niestandardowy przycisk, który rozszerza przycisk. Jeśli tło jest ustawione na coś innego niż tło domyślne (przez wywołanie albo setBackgroundResource(int id)
lub setBackgroundDrawable(Drawable d)
), chcę, aby marginesy były równe 0. Jeśli wywołam to:
public void setBackgroundToDefault() {
backgroundIsDefault = true;
super.setBackgroundResource(android.R.drawable.btn_default);
// Set margins somehow
}
Chcę, aby marginesy zostały zresetowane do -3dp (już czytałem tutaj, jak przekonwertować z pikseli na dp, więc kiedy już wiem, jak ustawić marginesy w px, sam mogę zarządzać konwersją). Ale ponieważ jest to wywoływane w CustomButton
klasie, rodzic może różnić się od LinearLayout do TableLayout i wolałbym, aby nie pobierał jego rodzica i nie sprawdzał instancji tego rodzica. Wyobrażam sobie, że to również będzie nieskuteczne.
Ponadto, podczas wywoływania (przy użyciu LayoutParams) parentLayout.addView(myCustomButton, newParams)
, nie wiem, czy to dodaje go do prawidłowej pozycji (nie próbowałem jednak), powiedz środkowy przycisk z rzędu pięciu.
Pytanie: Czy jest jakiś łatwiejszy sposób programowego ustawienia marginesu jednego przycisku niż użycie LayoutParams?
EDYCJA: Znam sposób LayoutParams, ale chciałbym rozwiązania, które pozwoli uniknąć obsługi każdego innego typu kontenera:
ViewGroup.LayoutParams p = this.getLayoutParams();
if (p instanceof LinearLayout.LayoutParams) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)p;
if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
this.setLayoutParams(lp);
}
else if (p instanceof RelativeLayout.LayoutParams) {
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)p;
if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
this.setLayoutParams(lp);
}
else if (p instanceof TableRow.LayoutParams) {
TableRow.LayoutParams lp = (TableRow.LayoutParams)p;
if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
this.setLayoutParams(lp);
}
}
Dlatego this.getLayoutParams();
zwraca ViewGroup.LayoutParams
, które nie posiadają atrybuty topMargin
, bottomMargin
, leftMargin
, rightMargin
. Instancja MC, którą widzisz, to po prostu MarginContainer
margines przesunięcia (-3dp) i (oml, omr, omt, omb) oraz oryginalne marginesy (ml, mr, mt, mb).
LayoutParams - NIE DZIAŁA! ! !
Potrzebujesz użyć typu: MarginLayoutParams
Przykład kodu dla MarginLayoutParams:
http://www.codota.com/android/classes/android.view.ViewGroup.MarginLayoutParams
źródło
Button
widoku:ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) button.getLayoutParams()
zwracanull
Najlepszy sposób:
Jak wywołać metodę:
Mam nadzieję, że to ci pomoże.
źródło
Następnie
Lub
źródło
Oto odpowiedź typu „wszystko w jednym” z najnowszymi aktualizacjami:
Krok 1, aby zaktualizować margines
Podstawowym pomysłem jest uzyskanie marginesu, a następnie jego aktualizacja. Aktualizacja zostanie zastosowana automatycznie i nie trzeba jej cofać. Aby uzyskać parametry układu, wystarczy wywołać tę metodę:
LayoutParams
Pochodzi z układu widoku. Jeśli widok pochodzi z układu liniowego, musisz zaimportowaćLinearLayout.LayoutParams
. Jeśli używasz względnego układu, importuLinearLayout.LayoutParams
itp.Teraz, jeśli ustawić margines użyciu
Layout_marginLeft
,Right
itp, trzeba marginesu aktualizacji w ten sposóbJeśli ustawisz margines za pomocą nowego
layout_marginStart
, musisz zaktualizować margines w ten sposóbKrok 2, aby zaktualizować margines w dp
Wszystkie dwa sposoby aktualizacji marginesu powyżej są aktualizowane w pikselach. Musisz wykonać tłumaczenie dp na piksele.
Teraz umieść obliczoną wartość w powyższych funkcjach aktualizacji marginesów i wszystko powinno być ustawione
źródło
layout_margin jest ograniczeniem, które dziecko widoku przekazuje swojemu rodzicowi. Jednak rolą rodzica jest wybór, czy zezwolić na margines, czy nie. Zasadniczo, ustawiając android: layout_margin = "10dp", dziecko błaga nadrzędną grupę widoków o przydzielenie miejsca o 10dp większego niż jego rzeczywisty rozmiar. (z drugiej strony padding = „10dp” oznacza, że widok potomny zmniejszy swoją zawartość o 10dp ).
W związku z tym nie wszystkie grupy ViewGroup przestrzegają marginesu . Najbardziej znanym przykładem byłby widok listy, w którym marginesy elementów są ignorowane. Przed wywołaniem
setMargin()
LayoutParam należy zawsze upewnić się, że bieżący widok znajduje się w grupie ViewGroup, która obsługuje margines (np. LinearLayouot lub RelativeLayout), i rzutować wynikgetLayoutParams()
na określone LayoutParams, które chcesz. (ViewGroup.LayoutParams
nawet nie masetMargins()
metody!)Poniższa funkcja powinna załatwić sprawę. Pamiętaj jednak o zastąpieniu RelativeLayout typem widoku nadrzędnego.
źródło
Ta metoda pozwoli Ci ustawić Margines w DP
AKTUALIZACJA
Możesz zmienić parametr, który odpowiada Twoim potrzebom.
źródło
W Kotlinie będzie to wyglądać tak:
źródło
Gdy jesteś w widoku niestandardowym, możesz użyć
getDimensionPixelSize(R.dimen.dimen_value)
, w moim przypadku, dodałem margines w LayoutParams utworzonychinit
metodą.W Kotlinie
w Javie:
źródło
Użyj tej metody, aby ustawić margines w dp
wywołaj metodę:
źródło
Do szybkiego ustawienia w jednej linii
ale zachowaj ostrożność w przypadku jakiegokolwiek niewłaściwego użycia LayoutParams, ponieważ nie będzie to miało
if
sprawdzania wystąpienia instrukcjiźródło
Utworzono funkcję rozszerzenia Kotlin dla tych, którzy mogą się przydać.
Pamiętaj, aby przekazywać w pikselach, a nie dp. Miłego kodowania :)
źródło
W moim przykładzie programowo dodaję ImageView do LinearLayout. Ustawiłem górny i dolny margines na ImagerView. Następnie dodaj ImageView do LinearLayout.
źródło
Możesz użyć tej metody i umieścić statyczny dimen, taki jak 20, który konwertuje zgodnie z urządzeniem
źródło
Jak dzisiaj, najlepiej jest użyć Paris , biblioteki dostarczanej przez AirBnB.
Style można następnie zastosować w następujący sposób:
obsługuje również widok niestandardowy (jeśli rozszerzysz widok) za pomocą adnotacji:
źródło
Musisz zadzwonić
tak:
your_view.setPadding(0,16,0,0)
To, czego próbujesz użyć, to tylko getter.
Android studio pokazuje, co
padding...()
tak naprawdę znaczy w java:przykład wypełnienia Obraz pokazuje, że są tylko wywołania
getPadding...()
Jeśli chcesz dodać margines do TextView, musisz mieć LayoutParams:
źródło
Musiałem rzucić mój
FrameLayout
na liniowy układ, ponieważ dziedziczy po nim i ustawiał tam marginesy, więc aktywność pojawia się tylko na części ekranu wraz z innym tłem niż oryginalne parametry układu wsetContentView
.Żadna z pozostałych osób nie pracowała nad użyciem tej samej aktywności i zmianą marginesów w oparciu o otwarcie aktywności z innego menu! setLayoutParams nigdy dla mnie nie działał - urządzenie ulegało awarii za każdym razem. Mimo że są to liczby zakodowane na stałe - jest to tylko przykład kodu wyłącznie do celów demonstracyjnych.
źródło
Możesz użyć
ViewGroup.MarginLayoutParams
do ustawienia szerokości, wysokości i marginesówGdzie metoda
setMargins();
przyjmuje wartości odpowiednio dla lewej, górnej, prawej, dolnej. Zgodnie z ruchem wskazówek zegara !, zaczynając od lewej.źródło