是否可以在约束布局上实现负边距以实现重叠?

推荐答案

UpdateConstraintLayout现在支持版本2.1.0-alpha2的负边距.简单地说

android:layout_marginTop="-25dp"

为负25分贝的利润.(这仅在视图顶部受约束时有效.如果边距的侧面不受约束,边距在ConstraintLayout中无效.)



Clarification:下面的答案仍然有效,但我想澄清几件事.原始解决方案将放置相对于另一个视图具有de facto负偏移的视图(如上所述),并将显示在布局中,如图所示.

另一种解决方案是按照Amir Khorsandi here的建议使用translationY属性.我更喜欢更简单的解决方案,但有一点需要注意:转换发生在post-layout,因此约束到位移视图的视图不会跟随转换.

例如,下面的XML在图像的正下方显示两个TextViews.每个视图都受到自上而下的约束,视图显示在其正上方.

enter image description here

<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"

这将产生以下结果:

enter image description here

"说出我的名字"TextView已经像预期的那样向上移动,但"说出我的名字"TextView并没有像我们预期的那样跟进.这是因为翻译发生在post-layout.尽管视图会移动帖子布局,但仍可以在新位置单击.

所以,依我看,如果上面的警告不影响你的布局,ConstraintLayout中的负利润率用translationXtranslationY;否则,使用下面概述的space小部件.

Another caveat:正如Salam El Banna在对另一个答案的 comments 中所述,translationX对于RTL布局来说不是一个好的解决方案,因为无论布局的RTL或LTR性质如何,翻译符号都会指示移位的方向(左/右).


Original answer

虽然ConstraintLayout中似乎不支持负边距,但有一种方法可以使用可用和支持的工具实现效果.这是一幅图像,其中图像标题与图像底部22dp重叠——实际上是-22dp页边距:

enter image description here

这是通过使用底部边距等于所需偏移量的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>

Android相关问答推荐

如何使TextField的背景透明?

如何使用Gradle风味在两个Kotlin导入(Google vs Amazon Java billing library)之间进行 Select ?

无法安装后重新编译android代码'

对支持哪些数据存储区方法感到困惑

LocalContext.current的问题(@Composable调用只能从@Composable函数的上下文发生)

空数据来自改装

可以';t将数据插入房间数据库

如何在使用 PointerInput 修改器时添加点击时的波纹效果

制作圆形SupportMapFragment

在java android studio项目上安装mapbox

Jetpack Compose 中的用户在线指示器

更改当前活动并返回后,Android webview 滚动不起作用

在 kotlin 中动态添加 GridView

围绕动态大小的内容包装 Jetpack Compose Row?

Jetpack compose :使用 rememberSaveable 时未应用待处理的合成

Android工作室未成立

Android Transitions API - 在 24-48 小时后停止接收任何更新

没有互联网连接时,Firebase Storage putFile() 永远不会完成

Hilt 依赖注入重复绑定错误

当我更改 ViewModel var 时,Kotlin + Compose 中的 Composable 不会更新