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

时间:2013-09-11 07:43:05

标签: 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>

看起来像这样:

basic setup

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

130dp in each direction of alignment

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

enter image description here

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

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

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

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

enter image description here

并且在保证金之后:

enter image description here

FrameLayout始终将视图保持原始大小,只需让视图“退出”即可。我尝试在至少应该在RelativeLayout之外的视图大小的相反方向给出负边距,并且看到与默认情况下FrameLayout中发生的行为相同的行为。

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

1 个答案:

答案 0 :(得分:3)

为什么它只能部分可见?

  

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

该框越来越小,因为我们不惜一切代价将其保留在父版面内,同时仍然应用保证金。由于较小的子视图为50dp,因此您添加了130dp的边距,所需的总宽度为180dp,但父视图本身仅为150dp宽。那是130dp + 50dp > 150dp - 孩子加边距不适合父母。

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

130dp + 20dp == 150dp

基本上,它会将内框的宽度从指定的50dp缩小到20dp,以便它可以适应父级内部及其附加边距。如果你看一下正方形20dp看起来正确的大小。它小了60%。

这是解释器的聪明行为,因为当屏幕大小发生变化并且遇到这样的问题时,它应该始终保留与宽度约束相对的边距约束。

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

当你说“这应该是部分可见的”时,我假设你认为孩子将在父界限内呈现一半,而在父界限之外呈现一半,类似于Windows表单开发。但情况并非如此,因为它总是会在大多数布局中将孩子置于父母的范围内。

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


在第二种情况下:

  

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

你超越了解释器缩小图像的程度。它无法将图像缩小为负1.即

50dp + 151dp > 150dp

它无法满足您提供的此保证金限制,因此行为相当不可预测。猜测我会说它知道它不能保留两个图像,以及它们在父母内部的边距。因此,它只是在内部和外部呈现一个。

再一次,这是愚蠢的输入,解释器正在尽力渲染你想要的东西。


  

任何人都可以解释行为上的差异以及相反的负边际效应吗?

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

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

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

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

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