Demo ujemnej marży:
Scenariusz
Nakładające się widoki poprzez ustawienie ujemnego marginesu dla jednego z nich, tak aby naruszał obwiednię innego widoku.
Myśli
Wydaje się, że działa tak, jak można się spodziewać, z nakładaniem się układów, jeśli powinny. Ale nie chcę napotkać większego problemu, ponieważ nieświadomie nie robię rzeczy dobrze. Emulatory, fizyczne urządzenia, jak to nazywasz, kiedy używasz ujemnych marginesów, wszystko wydaje się działać poprawnie, jeden widok narusza obwiednię innych widoków iw zależności od tego, jak jest zadeklarowany w układzie, będzie powyżej lub poniżej drugiego widoku.
Jestem też świadomy, że od API 21 możemy ustawić translationZ
i elevation
atrybuty, aby widok pojawia się powyżej lub poniżej innych poglądów, ale moja sprawa zasadniczo wynika z faktu, że w dokumentacji dla layout_margin
atrybutów to wyraźnie określić, że wartości marginesów powinna być dodatnia , niech cytuję:
Fragment:
określa dodatkową przestrzeń po lewej, górnej, prawej i dolnej stronie tego widoku. Ta przestrzeń jest poza granicami tego widoku. Wartości marginesów powinny być dodatnie . Musi to być wartość wymiaru, która jest liczbą zmiennoprzecinkową z dołączoną jednostką, np. „14,5sp”. Dostępne jednostki to: px (piksele), dp (piksele niezależne od gęstości), sp (piksele skalowane w oparciu o preferowany rozmiar czcionki), w (cale), mm (milimetry) ...
Przez lata, odkąd zadałem to pytanie, nie miałem żadnych problemów z ujemnymi marżami, starałem się unikać ich używania w jak największym stopniu, ale nie napotkałem żadnych problemów, więc mimo że dokumentacja mówi, że nie jestem zbyt martwiłem się o to.
źródło
Odpowiedzi:
W 2010 roku @RomainGuy (główny inżynier Android) stwierdził, że ujemne marże miały nieokreślone zachowanie .
W 2011 roku @RomainGuy stwierdził, że można stosować ujemne marże na
LinearLayout
iRelativeLayout
.W 2016 roku @RomainGuy stwierdził, że nigdy nie były oficjalnie wspierane i nie będą obsługiwane przez
ConstraintLayout
.Jednak łatwo jest obejść to ograniczenie.
Dodaj widok pomocnika (wysokość 0 dp, szerokość ograniczona do elementu nadrzędnego) u dołu widoku podstawowego, u dołu dodaj żądany margines.
Następnie umieść swój widok poniżej tego, skutecznie pozwalając mu mieć „ujemny” margines, ale bez konieczności używania żadnej nieobsługiwanej wartości ujemnej.
źródło
android:clipChildren="false"
iandroid:clipToPadding="false"
gdzie wcześniej nie robiłeś, albo coś tak się psuje .Mam nadzieję, że to komuś pomoże. Oto działający przykładowy kod przy użyciu
ConstraintLayout
na podstawie odpowiedzi @ CommonsWare:Przykładowy kod:
Wynik:
źródło
Jeśli chcesz użyć ujemnego marginesu, ustaw wystarczające wypełnienie kontenera i jego clipToPadding na false i ustaw ujemny margines dla jego elementów podrzędnych, aby nie przycinał widoku potomnego!
źródło
W przeszłości mogła to być zła praktyka, ale dzięki Material Design i jego pływającym przyciskom akcji wydaje się być nieunikniona i wymagana w wielu przypadkach teraz. Zasadniczo, jeśli masz dwa oddzielne układy, których nie możesz umieścić w jednym RelativeLayout, ponieważ wymagają one wyraźnie oddzielnej obsługi (na przykład nagłówek i zawartość), jedynym sposobem na nałożenie FAB jest sprawienie, by wystawał z jednego układy z ujemnymi marginesami. A to stwarza dodatkowe problemy z klikalnymi obszarami.
źródło
Dla mnie, a jeśli chodzi o ustawienie ujemnej marży na TextView (zdaję sobie sprawę, że OP odnosi się do ViewGroup, ale szukałem problemów z ustawieniem ujemnych marginesów i wylądowałem tutaj) ... Znalazłem problem z 4.0.3 ( API 15) TYLKO i ustawienie
android:layout_marginTop
lubandroid:layout_marginBottom
na wartość ujemną, taką jak -2dp.Z jakiegoś powodu TextView w ogóle się nie wyświetla. Wydaje się, że „zniknął” z widoku (nie tylko niewidoczny).
Kiedy wypróbowałem to z innymi 3 wersjami layout_margin, nie widziałem problemu.
Zauważ, że nie próbowałem tego na prawdziwym urządzeniu, używa emulatora 4.0.3. To druga dziwna rzecz, którą znalazłem, a która dotyczyła tylko wersji 4.0.3, więc moja nowa zasada brzmi: zawsze teście z 4.0.3 emulatora :)
Udało mi się zmniejszyć dolny margines TextView, używając tego,
android:lineSpacingExtra="-2dp"
co działa, mimo że tak się stałoandroid:singleLine="true"
(i nie pomyślałbym, że odstępy między wierszami będą czynnikiem).źródło
Nie, nie powinieneś używać
negative margin
. zamiast tego powinieneś użyćtranslate
. Nawet jeśli ujemny margines czasem zadziała, kiedy programowo zmienisz układ, translate by pomogło. Widok nie przepełnia ekranu, gdy używasz marginesów.źródło
Wiem tylko, że było to możliwe przez dość krótki okres. Ale nie widzę z tym problemu. Po prostu pamiętaj o rozmiarach ekranu i tym podobnych, więc na pewno nie zrobisz przypadkowo elementów, które nie powinny nakładać się na ekran. (tzn. tekst na górze to prawdopodobnie zły pomysł).
źródło