如何在约束布局上实现重叠/负边距? [英] How to achieve overlap/negative margin on Constraint Layout?

查看:193
本文介绍了如何在约束布局上实现重叠/负边距?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在约束布局上实现负边距以实现重叠? 我正在尝试使图像位于布局的中心,并具有文本"视图,使其与x dp重叠.我尝试设置负的保证金值,但没有运气. 如果有办法实现这一点,那就太好了.

Is it possible to achieve negative margin on constraint layout to achieve overlap? I am trying to have a image centered on the layout and have a Text view such that it overlaps a by x dp. I tried setting negative margin value but no luck. It would be great if there is a way to achieve this.

推荐答案

澄清:以下答案仍然有效,但我想澄清两点.如上所述,原始解决方案将相对于另一个视图放置一个事实负偏移的视图,并将其显示在所示的布局中.

Clarification: The answer below remains valid, but I want to clarify a couple of things. The original solution will place a view with a de facto negative offset with respect to another view as stated and will appear in the layout as shown.

另一种解决方案是使用Amir Khorsandi在此处建议的 translationY 属性.我希望该解决方案更简单,但有一个警告:翻译发生在 post-layout 上,因此受限于位移视图的视图将不遵循翻译.

Another solution is to use the translationY property as suggested by Amir Khorsandi here. I prefer that solution as simpler with one caveat: The translation occurs post-layout, so views that are constrained to the displaced view will not follow the translation.

例如,以下XML在图像下方立即显示两个 TextViews .每个视图都从上到下受其上紧接的视图约束.

For example, the following XML displays two TextViews immediately below the image. Each view is constrained top-to-bottom with the view that appears immediately above it.

<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 却没有遵循我们的预期.这是因为翻译发生在布局后.尽管视图在布局后移动,但仍可以在新位置将其单击.

The "Say my name" TextView has shifted up as expected, but the "Say it" TextView has not followed it up as we might expect. This is because the translation occurs post-layout. Although the view moves post-layout, it can still be made clickable in the new position.

因此,IMO,如果上面的说明不影响您的布局,请在 ConstraintLayout 中使用 translationX translationY 来获取负边距;否则,请使用如下所述的 space 小部件.

So, IMO, go with translationX and translationY for negative margins in ConstraintLayout if the caveat above doesn't affect your layout; otherwise, go with the space widget as outlined below.

原始答案

尽管在ConstraintLayout中似乎没有支持负边距,但是有一种方法可以使用可用和受支持的工具来实现效果.这是一幅图像,其图像标题从图像底部开始22dp重叠-有效地是-22dp边距:

Although it doesn't appear that negative margins will be supported in ConstraintLayout, there is a way to accomplish the effect using the tools that are available and supported. Here is an image where the image title is overlapped 22dp from the bottom of the image - effectively a -22dp margin:

这是通过将 Space 小部件与底部边距等于所需的偏移量.然后,将Space小部件的底部限制为ImageView的底部.现在,您要做的就是将TextView的顶部和图像标题限制在Space小部件的底部. TextView将位于Space视图的底部,而忽略设置的边距.

This was accomplished by using a Space widget with a bottom margin equal to the offset that you want. The Space widget then has its bottom constrained to the bottom of the ImageView. Now all you need to do is to constrain the top of the TextView with the image title to the bottom of the Space widget. The TextView will be positioned at the bottom of the Space view ignoring the margin that was set.

以下是实现此效果的XML.我会注意到我使用Space是因为它很轻巧并且适合于这种类型的使用,但是我本可以使用另一种类型的View并使它不可见. (但是,您可能需要进行调整.)您还可以定义一个View,其边距为零,并且所需插入边界的高度为高,并将TextView的顶部限制为插入点.

The following is the XML that accomplishes this effect. I will note that I use Space because it is lightweight and intended for this type of use, but I could have used another type of View and made it invisible. (You will probably need to make adjustments, though.) You could also define a View with zero margins and the height of the inset margin you want, and constrain the top of the TextView to the top of the inset View.

然而,另一种方法是通过对齐顶部/底部/左侧/右侧来对TextView覆盖在ImageView顶部,并对边距/填充进行适当的调整.下面演示的方法的好处在于,无需大量计算就可以创建负余量.就是说,有几种方法可以解决这个问题.

Yet another approach would be to overlay the TextView on top of the ImageView by aligning tops/bottoms/lefts/right and make suitable adjustments to margins/padding. The benefit of the approach demonstrated below is that a negative margin can be created without a lot of computation. That is all to say that there are several ways to approach this.

更新:有关此技术的快速讨论和演示,请参阅Google Developers Medium

Update: For a quick discussion and demo of this technique, see the Google Developers Medium blog post.

ConstraintLayout XML的负边距

Negative Margin for 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>

这篇关于如何在约束布局上实现重叠/负边距?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆