Update个 ConstraintLayout现在支持版本2.1.0-alpha2的负边距.简单地说
android:layout_marginTop="-25dp"
为负25分贝的利润.(这仅在视图顶部受约束时有效.如果边距的侧面不受约束,边距在ConstraintLayout中无效.)
Clarification:下面的答案仍然有效,但我想澄清几件事.原始解决方案将放置相对于另一个视图具有de facto负偏移的视图(如上所述),并将显示在布局中,如图所示.
另一种解决方案是按照Amir Khorsandi here的建议使用translationY属性.我更喜欢更简单的解决方案,但有一点需要注意:转换发生在post-layout,因此约束到位移视图的视图不会跟随转换.
例如,下面的XML在图像的正下方显示两个TextViews.每个视图都受到自上而下的约束,视图显示在其正上方.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="150dp"
android:layout_height="150dp"
android:tint="#388E3C"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_action_droid" />
<TextView
android:id="@+id/sayName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say my name."
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintTop_toBottomOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintStart_toStartOf="@+id/imageView" />
<TextView
android:id="@+id/sayIt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say it."
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintEnd_toEndOf="@+id/sayName"
app:layout_constraintStart_toStartOf="@+id/sayName"
app:layout_constraintTop_toBottomOf="@id/sayName" />
</androidx.constraintlayout.widget.ConstraintLayout>
现在,让我们通过指定
android:translationY="-50dp"
这将产生以下结果:
"说出我的名字"TextView已经像预期的那样向上移动,但"说出我的名字"TextView并没有像我们预期的那样跟进.这是因为翻译发生在post-layout.尽管视图会移动帖子布局,但仍可以在新位置单击.
所以,依我看,如果上面的警告不影响你的布局,ConstraintLayout中的负利润率用translationX和translationY;否则,使用下面概述的space小部件.
Another caveat:正如Salam El Banna在对另一个答案的 comments 中所述,translationX对于RTL布局来说不是一个好的解决方案,因为无论布局的RTL或LTR性质如何,翻译符号都会指示移位的方向(左/右).
Original answer
虽然ConstraintLayout
中似乎不支持负边距,但有一种方法可以使用可用和支持的工具实现效果.这是一幅图像,其中图像标题与图像底部22dp
重叠——实际上是-22dp
页边距:
这是通过使用底部边距等于所需偏移量的Space
小部件来实现的.然后,Space
小部件的底部被约束到ImageView
的底部.现在,您需要做的就是将带有图像标题的TextView
的顶部约束到Space
小部件的底部.TextView
将定位在Space
视图的底部,忽略设置的边距.
下面是实现这种效果的XML.我会注意到,我使用Space
是因为它很轻,适合这种类型的使用,但我可以使用另一种类型的View
,使其不可见.(不过,你可能需要做出调整.)您还可以定义一个具有零边距和所需插入边距高度的View
,并将TextView
的顶部约束到插入View
的顶部.
另一种方法是通过对齐顶部/底部/左侧/右侧将TextView
覆盖在ImageView
之上,并对页边距/填充进行适当调整.下面演示的方法的好处是可以在不进行大量计算的情况下创建负边距.这就是说,有几种方法可以解决这个问题.
Update:有关这项技术的快速讨论和演示,请参阅Google Developers Medium blog post.
Negative Margin for 100 XML
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher" />
<android.support.v4.widget.Space
android:id="@+id/marginSpacer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="22dp"
app:layout_constraintBottom_toBottomOf="@+id/imageView"
app:layout_constraintLeft_toLeftOf="@id/imageView"
app:layout_constraintRight_toRightOf="@id/imageView" />
<TextView
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say my name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/marginSpacer" />
</android.support.constraint.ConstraintLayout>