Aclaración: La respuesta a continuación sigue siendo válida, pero quiero aclarar un par de cosas. La solución original colocará una vista con un desplazamiento negativo de facto con respecto a otra vista como se indica y aparecerá en el diseño como se muestra.
Otra solución es usar la propiedad translationY como sugiere Amir Khorsandi aquí . Prefiero esa solución más simple con una advertencia: la traducción se produce después del diseño , por lo que las vistas que están restringidas a la vista desplazada no seguirán la traducción.
Por ejemplo, el siguiente XML muestra dos TextViews inmediatamente debajo de la imagen. Cada vista está restringida de arriba a abajo con la vista que aparece inmediatamente encima.
<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>
Ahora, vamos a traducir el "Di mi nombre" Vista de Texto por 50dp
especificando
android:translationY="-50dp"
Esto produce lo siguiente:
El TextView "Diga mi nombre" se ha movido hacia arriba como se esperaba, pero el TextView " Dígalo " no lo ha seguido como podríamos esperar. Esto se debe a que la traducción se produce después del diseño . Aunque la vista se mueve después del diseño, aún se puede hacer clic en ella en la nueva posición.
Entonces, en mi opinión, vaya con translationX y translationY para márgenes negativos en ConstraintLayout si la advertencia anterior no afecta tu diseño; de lo contrario, utilice el widget de espacio como se describe a continuación.
Respuesta original
Aunque no parece que se admitirán márgenes negativos ConstraintLayout
, hay una manera de lograr el efecto utilizando las herramientas disponibles y compatibles. Aquí hay una imagen donde el título de la imagen se superpone 22dp
desde la parte inferior de la imagen, efectivamente un -22dp
margen:
Esto se logró mediante el uso de un Space
widget con un margen inferior igual al desplazamiento que desea. El Space
widget tiene su parte inferior restringida a la parte inferior del ImageView
. Ahora todo lo que necesita hacer es restringir la parte superior TextView
con el título de la imagen a la parte inferior del Space
widget. El se TextView
colocará en la parte inferior de laSpace
vista ignorando el margen que se estableció.
El siguiente es el XML que logra este efecto. Notaré que lo uso Space
porque es liviano y está pensado para este tipo de uso, pero podría haber usado otro tipo View
y hacerlo invisible. (Sin embargo, probablemente necesitará hacer ajustes). También puede definir a View
con márgenes cero y la altura del margen de inserción que desee, y restringir la parte superior de TextView
la parte superior de la inserción View
.
Otro enfoque más sería superponer la TextView
parte superior ImageView
alineando la parte superior / inferior / izquierda / derecha y hacer los ajustes adecuados en los márgenes / relleno. El beneficio del enfoque que se muestra a continuación es que se puede crear un margen negativo sin mucho cálculo. Eso es todo para decir que hay varias formas de abordar esto.
Actualización: para ver una discusión rápida y una demostración de esta técnica, consulte la publicación del blog de Google Developers Medium .
Margen negativo para 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>