Demonstração de margem negativa:
O cenário
Sobrepor as visualizações definindo uma margem negativa para uma delas de modo que invada a caixa delimitadora de outra visualização.
Pensamentos
Parece que funciona da maneira que você esperaria, com a sobreposição dos layouts, se necessário. Mas não quero ter um problema maior por não saber fazer as coisas direito. Emuladores, dispositivos físicos, o que você quiser, quando você usa margens negativas tudo parece funcionar corretamente, uma visão invade a caixa delimitadora de outras visões e dependendo de como está declarado no layout ficará acima ou abaixo da outra visão.
Também estou ciente de que, desde a API 21, podemos definir os atributos translationZ
e elevation
para fazer a exibição aparecer acima ou abaixo de outras exibições, mas minha preocupação vem basicamente do fato de que na documentação dos layout_margin
atributos está claramente especificado que os valores de margem devem ser positivos , vamos citação de mim:
Trecho:
especifica espaço extra nos lados esquerdo, superior, direito e inferior desta vista. Este espaço está fora dos limites desta vista. Os valores da margem devem ser positivos . Deve ser um valor de dimensão, que é um número de ponto flutuante anexado a uma unidade como "14,5 sp". As unidades disponíveis são: px (pixels), dp (pixels independentes da densidade), sp (pixels redimensionados com base no tamanho de fonte preferido), em (polegadas), mm (milímetros) ...
Nos anos desde que fiz essa pergunta originalmente, não tive problemas com margens negativas, tentei evitar usá-las o máximo possível, mas não encontrei nenhum problema, portanto, embora a documentação afirme que, eu também não preocupado com isso.
fonte
Respostas:
Em 2010, @RomainGuy (engenheiro principal do Android) afirmou que as margens negativas tinham comportamento não especificado .
Em 2011, @RomainGuy afirmou que você pode usar margens negativas em
LinearLayout
eRelativeLayout
.Em 2016, @RomainGuy afirmou que nunca foi oficialmente suportado e não será suportado por
ConstraintLayout
.No entanto, é fácil contornar essa limitação.
Adicione uma visualização auxiliar (altura 0 dp, largura restrita ao pai) na parte inferior de sua visualização de base e, na parte inferior, adicione a margem desejada.
Em seguida, posicione sua visualização abaixo desta, efetivamente permitindo que ela tenha uma margem "negativa", mas sem ter que usar qualquer valor negativo não suportado.
fonte
android:clipChildren="false"
eandroid:clipToPadding="false"
onde antes não precisava, ou coisas quebram assim .Espero que isso ajude alguém. Aqui está um exemplo de código de trabalho usando com
ConstraintLayout
base na resposta de @ CommonsWare:Código de amostra:
Resultado:
fonte
Caso você queira usar margem negativa, defina preenchimento suficiente para o container e seu clipToPadding como false e defina a margem negativa para seus filhos para que não corte a exibição dos filhos!
fonte
Pode ter sido uma prática ruim no passado, mas com o Material Design e seus botões de ação flutuantes, parece ser inevitável e necessário em muitos casos agora. Basicamente, quando você tem dois layouts separados que não podem ser colocados em um único RelativeLayout porque eles precisam de um tratamento distinto (pense no cabeçalho e no conteúdo, por exemplo), a única maneira de sobrepor o FAB é fazê-lo sobressair de um daqueles layouts usando margens negativas. E isso cria problemas adicionais com áreas clicáveis.
fonte
Para mim, e em relação à configuração de uma margem negativa em um TextView (eu percebo que o OP está se referindo a um ViewGroup, mas eu estava procurando problemas com a configuração de margens negativas e cheguei aqui) ... Encontrei um problema com 4.0.3 ( API 15) SOMENTE e a configuração de
android:layout_marginTop
ouandroid:layout_marginBottom
para um valor negativo, como -2dp.Por algum motivo, o TextView não é exibido. Parece ter "desaparecido" da vista (não apenas invisível).
Quando tentei fazer isso com as outras 3 versões do layout_margin, não vi o problema.
Observe que eu não tentei isso em um dispositivo real, estou usando um emulador 4.0.3. Esta é a segunda coisa estranha que descobri que afetou apenas a 4.0.3, então minha nova regra é sempre testar com um emulador 4.0.3 :)
Tenho sucesso com a redução da margem inferior de um TextView usando o
android:lineSpacingExtra="-2dp"
que funciona mesmo que eu tenhaandroid:singleLine="true"
(e então eu não teria pensado que o espaçamento entre linhas seria um fator).fonte
Não, você não deve usar
negative margin
. em vez disso, você deve usartranslate
. Mesmo que a margem negativa funcione em algum momento, ao alterar o layout de maneira programável, a tradução ajudará. E a visualização não pode ultrapassar a tela quando você usa a margem.fonte
Eu só sabia que isso era possível por um curto período de tempo. Mas não vejo problema nisso. Esteja ciente dos tamanhos de tela e outros, para ter certeza de não criar itens que não deveriam aparecer sobrepostos na tela acidentalmente. (ou seja, texto acima do texto é provavelmente uma má ideia.)
fonte