android - RelativeLayout 对齐父级 *side* + 边距 *side*

标签 android android-layout android-relativelayout android-framelayout

当您将 View 与布局的一侧对齐时,我注意到 RelativeLayout 中的一种奇怪行为 (任何一侧)并且在同一方向上具有较大的边距。

我有 2 个 RelativeLayouts,每个都包含一个简单的 View 。在一种布局中, View 与顶部和左侧对齐,在另一种布局中, View 与底部和右侧对齐:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <RelativeLayout 
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginTop="110dp"
        android:layout_gravity="center"
        android:background="#ff555555" >

        <View
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_alignParentTop="true"
            android:layout_alignParentLeft="true"
            android:background="#aa8711" />     
    </RelativeLayout>

    <RelativeLayout 
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:layout_marginBottom="110dp"
        android:layout_gravity="center"
        android:background="#ff555555" >

        <View
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true"
            android:background="#998877" />         
     </RelativeLayout>      
</FrameLayout>

看起来像这样:

basic setup

我在父对齐的每个方向上添加了 130dp 的边距。这意味着 View 应该在布局中仅部分可见。这就是发生的事情:

130dp in each direction of alignment

如您所见, View 现在小于原始大小,因为它们被推到了布局的“墙壁”上。接下来,我尝试提供比布局更大的边距,因此我在对齐的方向上给了它们 151dp 的边距。它看起来像这样:

enter image description here

右下对齐的 View 现在“脱离”布局,并再次与原来的大小相同。另一方面,左上对齐的 View 也处于其原始大小,但完全在布局内部而不是在布局之外。

我已经单独尝试过这个,并且在对齐的每个排列中都得到了相同的结果。

问题一:谁能解释这种不一致的行为?

我尝试了同样的方法,这次将其行为与 FrameLayout 的行为进行比较。 初始设置:

enter image description here

和之后的边距:

enter image description here

FrameLayout 始终保持 View 的原始大小,并简单地让 View “退出”它。我试图在至少应该在 RelativeLayout 之外的 View 大小的相反方向上给出负边距,并看到与 FrameLayout 中发生的相同行为默认情况下。

问题 2:谁能解释行为差异和相反的负边际效应?

最佳答案

为什么它只能部分可见?

I added 130dp of margin in each direction of parent alignment. That means that the view should be only partially visible in the layout

盒子越来越小,因为优先考虑不惜一切代价将其保留在父布局中,同时仍应用边距。由于较小的 subview 为 50dp,因此您添加了 130dp 的边距,它需要的总宽度为 180dp 但父 View 本身只有 150dp宽。即 130dp + 50dp > 150dp - 子项加上边距不能放入父项。

这是“愚蠢的输入”,XML 解释器正在尽最大努力呈现某些内容。它最终做出的决定是它可以改变子框的宽度并仍然遵守边距约束。或者在数学上

130dp + 20dp == 150dp

基本上,它会将内框的宽度从指定的 50dp 缩小到 20dp 以便它可以容纳在添加边距的父级内部。如果你看一下正方形 20dp 的大小,看起来差不多。它小了 60%。

这是解释器的聪明行为,因为随着屏幕尺寸的变化并遇到这样的问题,它应该始终保留边距约束而不是宽度约束。

总而言之,解释器正在尽最大努力适应盒子,以及它在其父级内的边距,这样做会使盒子更小。它选择在给定宽度上保留给定边距 - 可能是因为最顶层的父布局。

当您说“这应该是部分可见的”时,我假设您认为 child 将在父边界内渲染一半,在父边界外渲染一半,类似于 Windows 窗体开发。但事实并非如此,因为在大多数布局中,它总是试图将子级保持在父级的范围内。

所做的选择也取决于最顶层的父布局,某些布局可能更喜欢保留子框的宽度而不是边距,甚至将框渲染到父框之外。


第二种情况:

so I gave them 151dp of margin in the aligned directions.

您超出了解释器可以缩小图像的范围。它不能将图像缩小到负1。那是

50dp + 151dp > 150dp

它不能满足你给它的这个边距限制,所以它的行为是相当不可预测的。我猜我会说它知道它不能将这两个图像以及它们的边距都保留在父级中。所以它只是渲染一个内部和一个外部。

再一次,这是愚蠢的输入,解释器正在尽最大努力呈现您想要的内容。


Can anyone explain the difference in behavior and the opposite negative margin effect?

负边距会根据其父级中的布局类型以及对齐方式执行不同的操作。在框架布局中,它的行为与相对布局不同。通常,如果您正在查看负面布局,则您选择了错误的父容器,并且您正在尝试破解它以使其看起来正确。

我不知道你到底想做什么,但也许你只需要稍微调整一下你的思维过程,想想试图理解你给它的 XML 的糟糕解释。

您不会是第一个完全被 android 的 XML 布局弄糊涂的人。在布局中嵌套布局总是令人困惑,并且行为会根据边距、对齐方式、宽度等许多因素而变化。我认识的大多数人只是简单地使用它,直到它是正确的,然后尝试不同的容器布局类型来获得正确的设计.

简而言之,避免使用边距(如 flash 或 winforms)并在没有布局类型的情况下进行播放,以获得所需的内容。

希望对您有所帮助,对不起 tl;dr.

关于android - RelativeLayout 对齐父级 *side* + 边距 *side*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18735382/

相关文章:

android - 如何更改操作栏上菜单项的位置

android - ICS 中似乎被忽略的主题

android - 以编程方式检测 7 英寸和 10 英寸平板电脑

Android,适配器中的 RelativeLayout 导致错误

java - 如何在 Android Studio 中以半径显示 2 个标记的显示距离

java - 具有 Java 客户端和 Python 服务器的数据报套接字

android - 如何制作透明的AppCompat风格?

安卓 : 5 Buttons positions : The better way?

android - 如何在android中构建键盘提示布局

android - 我怎样才能找到从特定纬度和经度到周边地区的距离(以公里为单位)?