在ConstraintLayout上实现负边距以实现重叠是否可能? 我想让一张图片居中在布局上,并且有一个文本视图,使其重叠x dp。我尝试了设置负边距值,但没有成功。如果有一种方法可以实现这一点,那就太好了。
在ConstraintLayout上实现负边距以实现重叠是否可能? 我想让一张图片居中在布局上,并且有一个文本视图,使其重叠x dp。我尝试了设置负边距值,但没有成功。如果有一种方法可以实现这一点,那就太好了。
更新 ConstraintLayout现在支持负边距,版本为2.1.0-alpha2。只需声明即可。
android:layout_marginTop="-25dp"
对于一个负的25dp的边距。(只有当视图的顶部被限制时才会生效。如果边距的一侧未被限制,则在ConstraintLayout中边距无效。)
另一种解决方案是使用Amir Khorsandi here建议的translationY属性。我更喜欢这个解决方案,因为它更简单,但有一个注意点:翻译发生在后布局,因此约束到被替换视图的视图将不会跟随翻译。
例如,以下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>
现在,我们需要将“Say my name” TextView 上移50dp
,通过指定:
android:translationY="-50dp"
原始答案
虽然似乎ConstraintLayout
不支持负边距,但可以使用可用且受支持的工具来实现该效果。这是一张图像,在此图像标题从图像底部重叠22dp
- 实际上是一个-22dp
的边距:
空间
小部件来完成的。然后,将 空间 小部件的底部约束到 ImageView 的底部。现在,您只需要将带有图像标题的 TextView 的顶部与 Space 小部件的底部约束即可。 TextView 将位于 Space 视图的底部,忽略了设置的边距。
以下是实现此效果的XML。我注意使用 Space ,因为它重量轻,适用于此类用途,但是我也可以使用另一种类型的 View 并将其设置为不可见(尽管您可能需要进行调整)。您还可以定义一个具有零边距和所需插入边距的高度的 View ,并将 TextView 的顶部限制为插入 View 的顶部。
另一种方法是通过将 TextView
与 ImageView
叠加在一起,通过对齐顶部/底部/左侧/右侧并适当调整边距/填充来实现。下面展示的方法的好处是可以创建负边距而不需要进行大量计算。也就是说,有几种方法可以处理这个问题。
更新:有关此技术的快速讨论和演示,请参见 Google Developers Medium 博客文章。
ConstraintLayout
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>
android:layout_marginTop="-25dp"
。它没有任何效果。 - VanessaFandroid:layout_width="0dp" android:layout_height="0dp"
。在我花费半天时间解决这个问题后,它对我很有效。 - AndyBoy"androidx.constraintlayout:constraintlayout:2.1.3"
,但建议的解决方案仍然没有任何效果。 - VanessaF另一种方法是使用translationX
或translationY
,像这样:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:translationX="25dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
它将像android:layout_marginRight="-25dp"
一样工作
经过数小时的尝试寻找解决方案,我终于想出了以下方法。
我们考虑两个图像,image1和image2。将image2放置在image1的右下角。
我们可以使用Space小部件来重叠视图。
将Space小部件的四个边分别与image1的四个边约束。对于这个例子,将image2的左侧与Space小部件的右侧约束,将image2的顶部与Space小部件的底部约束。这将把image2与Space小部件绑定在一起,由于Space小部件从所有边都被约束,我们可以定义所需的水平或垂直偏差来移动image2。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Player">
<ImageView
android:id="@+id/image1"
android:layout_width="250dp"
android:layout_height="167dp"
android:src="@android:color/holo_green_dark"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Space
android:id="@+id/space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="@+id/image1"
app:layout_constraintEnd_toEndOf="@+id/image1"
app:layout_constraintHorizontal_bias="0.82"
app:layout_constraintStart_toStartOf="@+id/image1"
app:layout_constraintTop_toTopOf="@+id/image1"
app:layout_constraintVertical_bias="0.62" />
<ImageView
android:id="@+id/image2"
android:layout_width="82dp"
android:layout_height="108dp"
android:src="@android:color/holo_green_light"
app:layout_constraintStart_toEndOf="@+id/space"
app:layout_constraintTop_toBottomOf="@+id/space" />
</android.support.constraint.ConstraintLayout>
此外,为了将image2定位在image1的中心底部,我们可以使用Space小部件将image2的左右两侧分别约束到Space小部件的左右侧。同样地,通过更改image2与Space小部件之间的约束,我们可以将image2放置在任何位置。
这将有助于许多人
在我的情况下,我希望我的设计如此:
意思是我想让我的图片展示一半的宽度,因此基本上我需要一个负的实际图像宽度的一半的边距,但我的整个布局都在约束布局中,而约束布局不允许负边距,所以我通过以下代码来实现这个目标
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_launcher_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/guideline"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_begin="50dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
所以ImageView将以指南线的起点结束。效果与在50dp处负边距相同。
如果您的视图宽度不固定且以百分比表示,则可以使用百分比放置指南线并实现任何想要的效果
编码愉快 :)
将背景视图放置在主题视图后面
我想使用负边距在主题视图后面添加一个比主题视图比例更大的视图。我找到的解决方案是,在将其约束到主题的所有侧面时,缩放背景视图android:scaleX="1.2"
和android:scaleY="1.2"
。
<View
android:id="@+id/subjectBackground"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleY="1.2"
android:scaleX="1.2"
app:layout_constraintBottom_toBottomOf="@+id/subjectView"
app:layout_constraintEnd_toEndOf="@+id/subjectView"
app:layout_constraintStart_toStartOf="@+id/subjectView"
app:layout_constraintTop_toTopOf="@+id/subjectView" />
你只需要在布局中使用 Space 小部件
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Space
android:id="@+id/negative_margin"
android:layout_width="16dp"
android:layout_height="16dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toLeftOf="parent"/>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Widget who needs negative margin"
app:layout_constraintTop_toBottomOf="@+id/negative_margin"
app:layout_constraintLeft_toLeftOf="@+id/negative_margin" />
使用 translationX 和 translationY 可能适用于您的情况。
<TextView
android:id="@+id/tvText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="text"
android:translationX="-15dp"
android:translationY="10dp"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="@+id/imageView" />
这是我的解决方案
<com.oven.test.avatar
android:id="@+id/imageview_a"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginTop="28dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.oven.test.smallicon
android:id="@+id/small_icon_overlap_a"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="@+id/imageview_a"
app:layout_constraintTop_toTopOf="@+id/imageview_a"
app:layout_constraintVertical_bias="1"
android:layout_marginBottom="20dp"/>