Android 如何在约束布局上实现重叠/负边距?
是否可以在约束布局上实现负边距以实现重叠? 我试图有一个以布局为中心的图像,并有一个文本视图,使其与一个x dp重叠。我尝试设置负的边距值,但没有成功。 如果有办法做到这一点,那就太好了 在RelativeLayout中,官方从未支持负利润率CONSTRAINTLAOUT中不支持负边距。[…] --2016年6月8日Romain Guy 关注以下两个问题: 更新 ConstraintLayout现在支持2.1.0-alpha2版本的负边距。简单陈述Android 如何在约束布局上实现重叠/负边距?,android,android-constraintlayout,constraint-layout-chains,Android,Android Constraintlayout,Constraint Layout Chains,是否可以在约束布局上实现负边距以实现重叠? 我试图有一个以布局为中心的图像,并有一个文本视图,使其与一个x dp重叠。我尝试设置负的边距值,但没有成功。 如果有办法做到这一点,那就太好了 在RelativeLayout中,官方从未支持负利润率CONSTRAINTLAOUT中不支持负边距。[…] --2016年6月8日Romain Guy 关注以下两个问题: 更新 ConstraintLayout现在支持2.1.0-alpha2版本的负边距。简单陈述 android:layout_marginT
android:layout_marginTop="-25dp"
对于负25dp余量。(他们说这是办不到的!)
澄清:下面的答案仍然有效,但我想澄清几件事。原始解决方案将放置一个相对于另一个视图实际负偏移的视图,如图所示,并将显示在布局中 另一个解决方案是使用Amir Khorsandi建议的translationY属性。我更希望该解决方案更简单,但有一点需要注意:转换发生在布局后,因此受置换视图约束的视图不会跟随转换 例如,下面的XML在图像的正下方显示两个文本视图。每个视图都受到从上到下的约束,且视图显示在其正上方 这将产生以下结果: “说出我的名字”文本视图已按预期向上移动,但“说出我的名字”文本视图并没有按预期向上移动。这是因为翻译发生在布局后。尽管视图移动了后期布局,但仍可以在新位置单击该视图 因此,在我看来,如果上述警告不影响您的布局,请在ConstraintLayout中使用translationX和translationY作为负边距;否则,使用下面概述的space小部件 另一个警告:正如Salam El Banna在对另一个答案的评论中所述,translationX对于RTL布局不是一个好的解决方案,因为无论布局的RTL或LTR性质如何,翻译的符号将指示移位的方向(左/右)
原始答案 虽然
ConstraintLayout
中似乎不支持负边距,但有一种方法可以使用可用和支持的工具实现此效果。这是一幅图像,其中图像标题与图像底部的22dp
重叠-实际上是-22dp
边距:
这是通过使用一个底部边距等于所需偏移量的小部件来实现的。然后,空间
小部件将其底部约束到图像视图
的底部。现在,您需要做的就是将带有图像标题的文本视图的顶部约束到空间
小部件的底部。TextView
将位于空间的底部
视图,忽略已设置的边距
以下是实现此效果的XML。我会注意到我使用了空间
,因为它是轻量级的,适合这种类型的使用,但我可以使用另一种类型的视图
,使其不可见。(不过,您可能需要进行调整。)您还可以定义一个边距和插入边距高度为零的视图,并将文本视图的顶部约束到插入视图的顶部
另一种方法是通过对齐顶部/底部/左侧/右侧,将文本视图
覆盖在图像视图
的顶部,并对边距/填充进行适当调整。下面演示的方法的好处是,无需大量计算即可创建负裕度。也就是说,有几种方法可以实现这一点
更新:有关此技术的快速讨论和演示,请参阅Google开发者媒体
约束列表的负边距
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>
我找到了一种更简单的方法 基本上有ImageView,然后在文本视图上添加top constraint以匹配图像的top constraint,只需添加TextView的边距top以匹配即可实现-ve边距类型行为。一种简单的方法 我不确定最好的办法 只需使用LinearLayout进行包装
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<View
android:layout_width="wrap_content"
android:layout_marginLeft="-20dp"
android:layout_height="wrap_content"/>
</LinearLayout>
另一种方法是使用
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\u marginRight=“-25dp”经过数小时的努力,我终于找到了解决方案 我们考虑两个图像IMAGE1和IMAGE2。将图像2放置在图像1的顶部,图像1位于右下侧 重叠视图示例 我们可以使用Space小部件处理重叠视图 分别用image1的四边约束空间小部件的四边。对于本例,将image2的左侧约束为空间小部件的右侧,将image2的顶部约束为空间小部件的底部。这将把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的中间底部,我们可以分别用空格小部件的左侧和右侧约束image2的左侧和右侧。类似地,我们可以通过使用Space widget更改image2的约束来将image2放置在任何位置。这将帮助许多人
在我的情况下,我希望我的设计如下:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:translationX="25dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
表示我希望我的图像显示其宽度的一半,以便
<?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>
<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>
<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" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="55dp"
android:layout_height="55dp"
app:layout_constraintBottom_toBottomOf="@+id/parent_view_id"
app:layout_constraintTop_toBottomOf="@+id/parent_view_id"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent" />
<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" />
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MyProfileFragment">
<ImageView
android:id="@+id/imageViewUserPic"
android:layout_width="@dimen/dp60"
android:src="@mipmap/ic_launcher"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_margin="20dp"
android:layout_height="wrap_content">
</ImageView>
<ImageView
android:id="@+id/imageViewEdit"
app:layout_constraintBottom_toBottomOf="@+id/imageViewUserPic"
android:src="@drawable/ic_edit_red_round"
app:layout_constraintEnd_toEndOf="@+id/imageViewUserPic"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
</androidx.constraintlayout.widget.ConstraintLayout>
<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"/>