Android中的非对称相对论行为

Android中的非对称相对论行为,android,layout,android-relativelayout,Android,Layout,Android Relativelayout,以下两个布局文件产生不同的结果: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" an

以下两个布局文件产生不同的结果:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:gravity="center">
  <RelativeLayout
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:gravity="center">
    <View
      android:id="@+id/box"
      android:background="#ff0000"
      android:layout_width="0dp"
      android:layout_height="30dp"
      android:layout_alignParentLeft="true"
      android:layout_toLeftOf="@+id/next_box" />
    <View
      android:id="@+id/next_box"
      android:background="#0000ff"
      android:layout_width="60dp"
      android:layout_alignParentRight="true"
      android:layout_height="30dp"
      />
  </RelativeLayout>
</LinearLayout>

结果:


结果:


两种布局都试图描述相同的约束。也就是说,红色矩形应该接触父对象的左边缘,蓝色矩形应该接触父对象的右边缘,并且它们应该在水平方向上彼此相邻。唯一的区别是在红色矩形还是蓝色矩形上指定“next to”约束。我找到了与通过形成约束的依赖关系图生成的度量解析顺序有关的原因,但我只是通过阅读RelativeLayout的源代码才找到了它,并且我找不到任何关于此行为的文档/注释。因为RelativeLayout必须是一个常用的布局组件,所以对于这种行为是否有更直观的解释,或者是否有我缺少的文档部分?

尽管两者似乎描述了相同的约束,但实际上它们并没有。区别在于,一个说红色必须坐在蓝色旁边,而另一个说蓝色必须坐在红色旁边。一个意思是,无论何时红色变为蓝色都必须跟随,另一个意思是,无论何时蓝色变为红色都必须跟随,他们都想去不同的地方

在第一个实例中,红盒依赖于蓝盒,因此首先构造蓝盒。蓝色框的宽度为60dp,因此首先构造一个60dp蓝色框,并将其向右对齐。然后是红色框,它有一个约束条件,必须坐在蓝色框旁边。宽度0被忽略,因为它需要位于60dp蓝色旁边并向左对齐

在第二个实例中,蓝框依赖于红框,因此首先构造红框。红色框表示需要0dp并向左对齐,因此无法看到。然后是蓝色的盒子,它需要坐在看不见的红色旁边并向右对齐,从而占据整个空间,其宽度被忽略


希望这有意义:)

所有这些参数定义在:

视图左边缘和右边缘(childParams.mLeft、childParams.mRight)基于锚定视图参数(anchorParams)进行计算。从该代码中,可以通过ALIGN_RIGHT(android:layout_alignRight)或ALIGN_PARENT_RIGHT(android:layout_alignParentRight)重新计算由LEFT_of(android:layout_toLeftOf)定义的视图的右边缘childParams.m。以下是0宽度红色视图变为大于0的原因解释

    <View
        android:id="@+id/box"
        android:background="#ff0000"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/next_box"/>
在这种情况下,锚定视图是:

    <View
        android:id="@+id/next_box"
        android:background="#0000ff"
        android:layout_width="60dp"
        android:layout_alignParentRight="true"
        android:layout_height="30dp"
        />
此视图的左边缘锚定视图的左边缘为0,因为android:layout_alignParentLeft=“true”且未定义边距=>childParams.mLeft=0

对于第二个示例,可以进行相同的计算: childParams.mRight=屏幕宽度
childParams.mLeft=0

您已将
布局宽度属性或第一个
视图设置为0。在第一种情况下,
RelativeLayout
显式地为其指定剩余宽度,正如您定义的左对齐和右对齐一样。在第二种情况下,没有定义右对齐,因此它是以0宽度向左布局,而另一个
视图
采用所有可用宽度,因为它被明确定义为与第一个
视图
的右边框对齐。感谢您的澄清,正如我在最后一段中所说,我知道两者之间的区别,但我认为Android文档中没有任何地方记录过这种区别,这可能会让人很困惑。这是安卓社区默默理解的吗?@dementrock:记录什么?这些约束的行为完全符合定义,而且只有这样才有意义。我认为,对于Android及其怪癖,永远不会有足够的文档。当时我快速浏览了RelativeLayout文档,发现它有点太简短了。如果有更多你能读到的东西就好了。对我来说,使用RelativeLayout是一种尝试和错误,用你的直觉来确定它为什么会这样。@corsair992问题是RelativeLayout所做的不是共同解决约束满足问题。相反,它基于指定的约束构造依赖关系图,并基于这些依赖关系按顺序解析每个视图的位置和大小。作为一名开发人员,它需要一种不同的思维方式,因为您不仅需要提出一组约束,还需要指定这些约束的特定顺序。这就是为什么我认为这种行为确实需要正式记录下来,或者至少在社区的某个地方进行解释。@dementrock:依赖关系图仅用于满足约束,如果满足所有约束是可能的。不需要顺序,只需要定义所需布局的约束集合。与简单的布局相比,它确实需要更多的思考,但这也是它被设计为强大而灵活的布局管理器的原因。我在这里没有看到任何需要记录的东西,而且它们在任何情况下都是非常自我解释的。
    <View
        android:id="@+id/box"
        android:background="#ff0000"
        android:layout_width="0dp"
        android:layout_height="30dp"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@+id/next_box"/>
childParams.mRight = anchorParams.mLeft - (anchorParams.leftMargin +
                    childParams.rightMargin);
    <View
        android:id="@+id/next_box"
        android:background="#0000ff"
        android:layout_width="60dp"
        android:layout_alignParentRight="true"
        android:layout_height="30dp"
        />
childParams.mLeft = mPaddingLeft + childParams.leftMargin;