Clarification: La réponse ci-dessous reste valable, mais je tiens à clarifier quelques points. La solution d'origine placera une vue avec un décalage négatif de facto par rapport à une autre vue comme indiqué et apparaîtra dans la mise en page comme indiqué.
Une autre solution consiste à utiliser la propriété translationY comme suggéré par Amir Khorsandi ici . Je préfère que cette solution soit plus simple avec une mise en garde: la traduction se produit après la mise en page , donc les vues qui sont contraintes à la vue déplacée ne suivront pas la traduction.
Par exemple, le code XML suivant affiche deux TextViews immédiatement sous l'image. Chaque vue est contrainte de haut en bas avec la vue qui apparaît immédiatement au-dessus.
<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>
Maintenant, nous allons traduire le « Say my name » TextView par 50dp
en spécifiant
android:translationY="-50dp"
Cela produit ce qui suit:
Le TextView "Dites mon nom" s'est déplacé vers le haut comme prévu, mais le TextView "Dites-le" ne l' a pas suivi comme on pouvait s'y attendre. En effet, la traduction a lieu après la mise en page . Bien que la vue se déplace après la mise en page, elle peut toujours être rendue cliquable dans la nouvelle position.
Donc, OMI, optez pour translationX et translationY pour les marges négatives dans ConstraintLayout si la mise en garde ci-dessus n'affecte pas votre mise en page; sinon, utilisez le widget d' espace comme indiqué ci-dessous.
Réponse originale
Bien qu'il ne semble pas que les marges négatives soient prises en charge dans ConstraintLayout
, il existe un moyen d'obtenir l'effet en utilisant les outils disponibles et pris en charge. Voici une image où le titre de l'image se chevauche 22dp
depuis le bas de l'image - en fait une -22dp
marge:
Cela a été accompli en utilisant un Space
widget avec une marge inférieure égale au décalage souhaité. Le Space
widget a alors son bas contraint au bas du fichier ImageView
. Il ne vous reste plus qu'à contraindre le haut du TextView
avec le titre de l'image au bas du Space
widget. Le TextView
sera positionné en bas de la Space
vue en ignorant la marge qui a été définie.
Voici le XML qui accomplit cet effet. Je noterai que je l'utilise Space
car il est léger et destiné à ce type d'utilisation, mais j'aurais pu utiliser un autre type de View
et le rendre invisible. (Vous devrez probablement faire des ajustements, cependant.) Vous pouvez également définir un View
avec des marges nulles et la hauteur de la marge de l'encart que vous voulez, et contraindre TextView
le haut de l'encart au haut de l'encart View
.
Une autre approche encore consisterait à superposer TextView
le dessus ImageView
en alignant dessus / bas / gauche / droite et faire des ajustements appropriés aux marges / rembourrage. L'avantage de l'approche démontrée ci-dessous est qu'une marge négative peut être créée sans beaucoup de calcul. Tout cela pour dire qu'il existe plusieurs manières d'aborder cela.
Mise à jour: pour une discussion rapide et une démonstration de cette technique, consultez l' article de blog Google Developers Medium .
Marge négative pour 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>