J'ai un ConstraintLayout avec deux vues A et B qui sont empilées verticalement. J'ai une troisième vue C qui doit être à la fin de A et B horizontalement. A tout moment, A peut être plus large que B ou inversement, la contrainte ne peut donc être basée que sur une seule vue. Existe-t-il un moyen de définir cette contrainte via la vue C?
Actuellement, je peux définir A et B pour que
app:layout_constraintEnd_toStartOf="C"
Cela fonctionne, mais comme il n’ya pas de contrainte de début en C, l’aperçu de conception ne dessine pas correctement d’autres propriétés telles que
app:layout_constraintHorizontal_bias="1.0"
Une autre option peut être de regrouper les groupes A et B. La plupart des questions sur le regroupement parlent de chaînes, ce qui, à mon avis, ne résout pas ce problème. Ajouter une autre vue pour envelopper les deux semble également aller à l'encontre du but de ConstraintLayout, qui est censé éliminer les enfants imbriqués.
Edit: J'ai ci-joint un exemple ci-dessous:
<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="wrap_content">
<TextView
Android:id="@+id/view_c"
Android:layout_width="wrap_content"
Android:layout_height="0dp"
Android:layout_marginStart="16dp"
Android:text="View C"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5" />
<TextView
Android:id="@+id/view_a"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginTop="16dp"
Android:text="View A"
app:layout_constraintBottom_toTopOf="@id/view_b"
app:layout_constraintEnd_toStartOf="@id/view_c"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginBottom="16dp" />
<TextView
Android:id="@+id/view_b"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginBottom="16dp"
Android:text="View B"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/view_c"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view_a" />
</Android.support.constraint.ConstraintLayout>
Dans ce cas, l'aperçu devrait afficher "View C" quelque part au milieu car son biais est 0.5. Cependant, il ne connaît pas sa limite de départ car ils sont définis dans view_a et view_b, et reste donc à l'extrême droite.
Solution:
Ci-dessous ma mise en page finale dans son intégralité
<?xml version="1.0" encoding="utf-8"?>
<!--due to animations, we need a wrapper viewgroup so our changes will stick-->
<LinearLayout 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="wrap_content"
Android:background="?android:attr/selectableItemBackground"
Android:baselineAligned="false"
Android:clipToPadding="false"
Android:minHeight="?android:attr/listPreferredItemHeightSmall"
Android:orientation="horizontal"
Android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
Android:paddingStart="?android:attr/listPreferredItemPaddingStart">
<Android.support.constraint.ConstraintLayout
Android:id="@+id/kau_pref_container"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<!--As per Android N, icons (24dp) are aligned to the left rather than centered-->
<ImageView
Android:id="@+id/kau_pref_icon"
Android:layout_width="56dp"
Android:layout_height="56dp"
Android:layout_marginBottom="4dp"
Android:layout_marginTop="4dp"
Android:contentDescription="@string/kau_pref_icon"
Android:paddingEnd="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5"
tools:layout_editor_absoluteX="0dp" />
<TextView
Android:id="@+id/kau_pref_title"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_marginTop="16dp"
Android:ellipsize="Marquee"
Android:textAppearance="?android:attr/textAppearanceListItem"
Android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/kau_pref_desc"
app:layout_constraintEnd_toStartOf="@+id/kau_pref_inner_frame"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/kau_pref_icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginBottom="16dp"
tools:layout_editor_absoluteX="-175dp" />
<TextView
Android:id="@id/kau_pref_desc"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_marginBottom="16dp"
Android:ellipsize="end"
Android:maxLines="10"
Android:textAppearance="?android:attr/textAppearanceListItemSecondary"
Android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/kau_pref_inner_frame"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/kau_pref_icon"
app:layout_constraintTop_toBottomOf="@id/kau_pref_title"
tools:layout_editor_absoluteX="-175dp" />
<Android.support.constraint.Barrier
Android:id="@+id/kau_pref_barrier"
Android:layout_width="1dp"
Android:layout_height="wrap_content"
app:constraint_referenced_ids="kau_pref_title,kau_pref_desc"
app:barrierDirection="end"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<LinearLayout
Android:id="@id/kau_pref_inner_frame"
Android:layout_width="wrap_content"
Android:layout_height="0dp"
Android:gravity="center_vertical|end"
Android:orientation="horizontal"
Android:paddingStart="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toEndOf="@id/kau_pref_barrier"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.5"
tools:layout_editor_absoluteX="1dp" />
</Android.support.constraint.ConstraintLayout>
</LinearLayout>
Il y a un titre et une description, et le contenu interne doit être à la fin des deux vues. J'ai également essayé Group, qui est également nouveau dans la version bêta de la configuration des contraintes, mais il ne s'ajuste pas lorsqu'un enfant est marqué comme parti.
Ceci peut être facilement réalisé en utilisant la nouvelle fonctionnalité Barriers
.
<?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"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<TextView
Android:id="@+id/view_c"
Android:layout_width="wrap_content"
Android:layout_height="0dp"
Android:text="View C"
app:layout_constraintLeft_toRightOf="@+id/barrier1"
app:layout_constraintTop_toTopOf="parent" />
<Android.support.constraint.Barrier
Android:id="@+id/barrier1"
Android:layout_width="1dp"
Android:layout_height="wrap_content"
app:barrierDirection="right"
app:constraint_referenced_ids="view_a, view_b"
app:layout_constraintTop_toTopOf="parent" />
<TextView
Android:id="@+id/view_a"
Android:layout_width="100dp"
Android:layout_height="wrap_content"
Android:layout_marginTop="16dp"
Android:text="View A"
app:layout_constraintBottom_toTopOf="@id/view_b"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginBottom="16dp" />
<TextView
Android:id="@+id/view_b"
Android:layout_width="200dp"
Android:layout_height="wrap_content"
Android:layout_marginBottom="16dp"
Android:text="View B"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/view_a" />
</Android.support.constraint.ConstraintLayout>
Comment utiliser les barrières?
Les barrières ressemblent à la construction d’un MUR HUUUUGE qui "protège" les vues mentionnées dans constraint_referenced_ids
. Donc, vous devez mentionner dans quelle direction il est "supposé rester en dehors" qui, dans notre cas, est le droit (view_c). Utilisez simplement l'attribut barrierDirection
.
Enfin, n'oubliez pas de vous assurer que view_c est dans la zone interdite (layout_constraintLeft_toRightOf="@+id/barrier1"
).
Comme cette fonctionnalité est disponible uniquement dans la version 1.1.0 beta1 de ConstraintLayout, n'oubliez pas d'ajouter cette ligne à votre fichier build.gradle.
compile 'com.Android.support.constraint:constraint-layout:1.1.0-beta1'
J'espère que cela t'aides!
J'ai essayé ceci dans mon IDE et je suis arrivé avec un code pour le faire dynamiquement à l'exécution
TextView viewa = (TextView) findViewById(R.id.view_a);
TextView viewb = (TextView) findViewById(R.id.view_b);
ConstraintLayout cl = (ConstraintLayout) findViewById(R.id.constraintLayout);
ConstraintSet cs = new ConstraintSet();
cs.clone(cl);
cs.connect(viewb.getWidth() > viewa.getWidth() ? R.id.view_b : R.id.view_a, ConstraintSet.RIGHT, R.id.view_c, ConstraintSet.LEFT);
cs.applyTo(cl);
Cela finit par le gâcher légèrement en poussant la vue plus large hors de l’écran de gauche. Peut-être que vous pourriez comprendre cela car je suis incapable de le faire à ce stade.