在 Android 中使用负边距是一种不好的做法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10673503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it a bad practice to use negative margins in Android?
提问by Juan Cortés
Demo of negative margin:
负保证金演示:
The scenario
场景
Overlapping views by setting a negative margin to one of them so that it invades the bounding box of another view.
通过为其中一个视图设置负边距来重叠视图,使其侵入另一个视图的边界框。
Thoughts
想法
It seems to work the way you'd expect with overlapping of the layouts if they should. But I don't want to run into a bigger problem for unknowingly not doing things right. Emulators, physical devices, you name it, when you use negative margins everything seems to work correctly, one view invades another's views bounding box and depending on how it's declared in the layout it will be above or below the other view.
如果应该的话,它似乎以您期望的方式工作,布局重叠。但我不想因为在不知不觉中做错事情而遇到更大的问题。模拟器,物理设备,你说出来的,当你使用负边距时,一切似乎都正常工作,一个视图侵入另一个视图的边界框,并且根据它在布局中的声明方式,它将位于另一个视图的上方或下方。
I'm also aware that since API 21 we can set the translationZ
and elevation
attributes to make view appear above or below other views but my concernbasically comes from the fact that in the documentationfor the layout_margin
attributes it's clearly specified that margin values should be positive, let me quote:
我也知道,从 API 21 开始,我们可以设置translationZ
和elevation
属性以使视图出现在其他视图的上方或下方,但我的担忧主要来自这样一个事实,即在layout_margin
属性的文档中,它明确指定了边距值应该为正,让我引用:
Excerpt:
Specifies extra space on the left, top, right and bottom sides of this view. This space is outside this view's bounds. Margin values should be positive. Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp". Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size), in (inches), mm (millimeters)...
摘录:
指定此视图左侧、顶部、右侧和底部的额外空间。这个空间在这个视图的边界之外。边距值应为正。必须是一个维度值,它是一个附加单位的浮点数,例如“14.5sp”。可用单位有:px(像素)、dp(与密度无关的像素)、sp(基于首选字体大小的缩放像素)、in(英寸)、mm(毫米)...
In the years since originally asking this question I haven't had any issues with negative margins, did try to avoid using them as much as possible, but did notencounter any issues, so even though the documentation states that, I'm not too worried about it.
在未来的几年,因为最初提出这个问题,我还没有切缘阴性的任何问题,并尽量避免使用它们尽可能多地,但并没有遇到任何问题,所以即使文档指出,我不是太担心它。
回答by CommonsWare
In 2010, @RomainGuy (core Android engineer) stated that negative margins had unspecified behavior.
2010 年,@RomainGuy(核心 Android 工程师)表示负利润有未指明的行为。
In 2011, @RomainGuy stated that you can use negative margins on LinearLayout
and RelativeLayout
.
2011 年,@RomainGuy 表示您可以在LinearLayout
和上使用负边距RelativeLayout
。
In 2016, @RomainGuy stated that they have never been officially supported and won't be supported by ConstraintLayout
.
2016 年,@RomainGuy 表示他们从未得到官方支持,也不会得到ConstraintLayout
.
It is easy to work around this limitation though.
不过,很容易解决这个限制。
Add an helper view (height 0dp, width constrained to parent) at the bottom of your base view, at the bottom add the margin you want.
Then position your view below this one, effectively allowing it to have a "negative" margin but without having to use any unsupported negative value.
在基本视图的底部添加一个辅助视图(高度 0dp,宽度受限于父视图),在底部添加所需的边距。
然后将您的视图放置在此视图下方,有效地允许它具有“负”边距,但不必使用任何不受支持的负值。
回答by Vikasdeep Singh
Hope this will help someone. Here is working sample code using ConstraintLayout
based on @CommonsWare's answer:
希望这会帮助某人。这是ConstraintLayout
基于@CommonsWare 的回答使用的工作示例代码:
Add an helper view (height 0dp, width constrained to parent) at the bottom of your base view, at the bottom add the margin you want. Then position your view below this one, effectively allowing it to have a "negative" margin but without having to use any unsupported negative value.
在基本视图的底部添加一个辅助视图(高度 0dp,宽度受限于父视图),在底部添加所需的边距。然后将您的视图放置在此视图下方,有效地允许它具有“负”边距,但不必使用任何不受支持的负值。
Sample code:
示例代码:
<TextView
android:id="@+id/below"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F1B36D"
android:padding="30dp"
android:text="I'm below"
android:textColor="#ffffff"
android:textSize="48sp"
android:textAlignment="center"
tools:layout_editor_absoluteX="129dp"
tools:layout_editor_absoluteY="0dp" />
<android.support.v4.widget.Space
android:id="@+id/space"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="@+id/below"
app:layout_constraintLeft_toLeftOf="@id/below"
app:layout_constraintRight_toRightOf="@id/below" />
<TextView
android:id="@+id/top"
android:layout_width="100dp"
android:layout_height="60dp"
android:textAlignment="center"
android:textColor="#ffffff"
android:text="I'M ON TOP!"
android:background="#676563"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/space" />
Output:
输出:
回答by Ali
In case you want use negative margin,set enough padding for container and its clipToPaddingto false and set negative margin for it's children so it won't clip the child view!
如果您想使用负边距,请为容器及其clipToPadding设置足够的填充为false 并为其子视图设置负边距,这样它就不会剪辑子视图!
回答by Gábor
It might have been bad practice in the past but with Material Design and its floating action buttons, it seems to be inevitable and required in many cases now. Basically, when you have two separate layouts that you can't put into a single RelativeLayout because they need distinctly separate handling (think header and contents, for instance), the only way to overlap the FAB is to make it stick out of one those layouts using negative margins. And this creates additional problems with clickable areas.
过去这可能是一种不好的做法,但是有了 Material Design 及其浮动操作按钮,现在在许多情况下似乎是不可避免的和必需的。基本上,当你有两个单独的布局,你不能把它们放在一个 RelativeLayout 中,因为它们需要明显单独的处理(例如,想想标题和内容),重叠 FAB 的唯一方法是让它伸出一个使用负边距的布局。这会给可点击区域带来额外的问题。
回答by Cheung Sean
No, you should not use negative margin
. instead you should use translate
. Even if negative margin work sometime, when you change layout programmably, translate would help. And view can't overflow the screen wen you use margin.
不,你不应该使用negative margin
. 相反,您应该使用translate
. 即使负边距有时有效,当您以可编程方式更改布局时,翻译也会有所帮助。并且视图不能溢出您使用边距的屏幕。
回答by GaryAmundson
For me, and regarding setting a negative margin on a TextView (I realize the OP is referring to a ViewGroup, but I was looking for issues with setting negative margins and I landed here)... I found a problem with 4.0.3 (API 15) ONLY and the setting of android:layout_marginTop
or android:layout_marginBottom
to a negative value such as -2dp.
对我来说,关于在 TextView 上设置负边距(我意识到 OP 指的是 ViewGroup,但我一直在寻找设置负边距的问题,我在这里登陆)......我发现 4.0.3 有问题( API 15) ONLY 以及将android:layout_marginTop
或设置为android:layout_marginBottom
负值,例如 -2dp。
For some reason the TextView does not display at all. It appears to be "gone" from the view (not just invisible).
由于某种原因,TextView 根本不显示。它似乎从视图中“消失了”(不仅仅是不可见)。
When I tried this with the other 3 versions of layout_margin, I didn't see the issue.
当我用其他 3 个版本的 layout_margin 尝试这个时,我没有看到这个问题。
Note that I haven't tried this on a real device, this is using a 4.0.3 emulator. This is the 2nd odd thing I've found that only affected 4.0.3, so my new rule is to alwaystest with a 4.0.3 emulator :)
请注意,我还没有在真实设备上尝试过,这是使用 4.0.3 模拟器。这是我发现的第二个仅影响 4.0.3 的奇怪事情,所以我的新规则是始终使用 4.0.3 模拟器进行测试:)
I have success with reducing the bottom margin of a TextView by using android:lineSpacingExtra="-2dp"
which works even though I happen to have android:singleLine="true"
(and so I wouldn't have thought that line spacing would be a factor).
我成功地通过使用android:lineSpacingExtra="-2dp"
which来减少 TextView 的底部边距,即使我碰巧有android:singleLine="true"
(所以我不认为行间距会是一个因素)。
回答by FoamyGuy
I've only known that it was possible for a rather short period of time. But I see no problem with it. Just be aware of screen sizes and such so you are sure not to accidentally make to items that shouldn't appear overlapped on the screen. (i.e. text on top of text is likely a bad idea.)
我只知道在相当短的时间内是可能的。但我认为没有问题。请注意屏幕尺寸等,这样您就可以确保不会意外制作不应出现在屏幕上重叠的项目。(即文本顶部的文本可能是一个坏主意。)