RelativeLayout对齐父*边*+边*方*

Ita*_*ski 19 android android-layout android-relativelayout android-framelayout

RelativeLayout当你将视图与布局的一侧(任何一侧)对齐并且在同一方向上有一个大的边距时,我注意到了一种奇怪的行为.

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

<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>
Run Code Online (Sandbox Code Playgroud)

它看起来像这样:

基本设置

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

每个对齐方向130dp

正如您所看到的,视图现在小于原始大小,因为它被推到了布局的"墙"上.接下来我试图给出一个比布局更大的边距,所以我在对齐的方向上给了它们151dp的边距.它看起来像这样:

在此输入图像描述

右下方对齐的视图现在"突破"布局,并且再次与原来的大小相同.另一方面,左上角对齐的视图也是原始大小,但完全在布局内部而不是在其外部.

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

问题一:任何人都可以解释这种不一致的行为吗?

我尝试了同样的事情,这次将行为与a的行为进行比较FrameLayout.初始设置:

在此输入图像描述

并且在保证金之后:

在此输入图像描述

FrameLayout保持在所有时间的原始大小视图和简单地让视图"退出"了.我尝试在至少应该在视图之外的视图的大小的相反方向给出负边距,RelativeLayout并且看到与FrameLayout默认情况下发生的行为相同的行为.

问题2:任何人都可以解释行为上的差异和相反的负边际效应吗?

Fad*_*orm 3

为什么它只能部分可见?

我在父对齐的每个方向上添加了 130dp 的边距。这意味着视图在布局中应该仅部分可见

盒子变得越来越小,因为人们优先考虑不惜一切代价将其保留在父布局内​​,同时仍然应用边距。由于较小的子视图是 50dp,因此您添加了边距130dp,它需要的总宽度是180dp,但父视图本身只有150dp宽度。也就是说130dp + 50dp > 150dp,子项加上边距无法放入父项内。

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

130dp + 20dp == 150dp
Run Code Online (Sandbox Code Playgroud)

基本上,它会缩小内部框的宽度,使其能够在添加边距的50dp情况20dp下适合父级。如果你看一下正方形的大小,20dp看起来就差不多了。它小了 60%。

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

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

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

所做的选择也取决于最顶层的父布局,某些布局可能更愿意保留子框的宽度而不是边距,甚至将框呈现在父边界之外。


在第二种情况下:

所以我在对齐方向上给了它们 151dp 的边距。

你已经超出了解释器可以缩小图像的范围。它不能将图像缩小到负1。即

50dp + 151dp > 150dp
Run Code Online (Sandbox Code Playgroud)

它无法满足您给它的边距约束,因此行为相当不可预测。我猜测它知道它不能将两个图像及其边距保留在父级内部。所以它只是渲染一个内部和一个外部。

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


谁能解释行为上的差异和相反的负边际效应?

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

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

您不会是第一个对 Android 的 XML 布局完全困惑的人。在布局中嵌套布局总是令人困惑,并且行为的变化取决于许多因素,例如边距、对齐方式、宽度等。我认识的大多数人只是简单地摆弄它,直到它正确为止,并尝试不同的容器布局类型以获得正确的设计。

简而言之,避免使用边距(例如 flash 或 winform),并且不使用布局类型,而是将内容放在您想要的位置。

希望有帮助,对不起,tl;博士。