Dans la ConstraintLayout
version 2.1, plusieurs fonctionnalités ont été ajoutées pour
gérer les appareils pliables, y compris SharedValues
,
ReactiveGuide
et amélioration de la prise en charge des animations avec MotionLayout
.
Valeurs partagées
Nous avons ajouté un nouveau mécanisme pour injecter des valeurs d'exécution dans ConstraintLayout
:
il est destiné à être utilisé pour les valeurs à l'échelle du système, car toutes les instances de
ConstraintLayout
peut accéder à la valeur.
Dans le contexte des appareils pliables, ce mécanisme permet d'injecter de la ligne de flottaison lors de l'exécution:
Kotlin
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)
Java
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);
Dans un assistant personnalisé, vous pouvez accéder aux valeurs partagées en ajoutant un écouteur pour toute modification:
Kotlin
val sharedValues: SharedValues = ConstraintLayout.getSharedValues() sharedValues.addListener(mAttributeId, this)
Java
SharedValues sharedValues = ConstraintLayout.getSharedValues(); sharedValues.addListener(mAttributeId, this);
Consultez l'exemple FoldableExperiments.
pour voir comment capturer la position du pli à l'aide de la
la bibliothèque Jetpack WindowManager et injecter
la position en ConstraintLayout
.
Kotlin
inner class StateContainer : Consumer<WindowLayoutInfo> { override fun accept(newLayoutInfo: WindowLayoutInfo) { // Add views that represent display features for (displayFeature in newLayoutInfo.displayFeatures) { val foldFeature = displayFeature as? FoldingFeature if (foldFeature != null) { if (foldFeature.isSeparating && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL ) { // The foldable device is in tabletop mode val fold = foldPosition(motionLayout, foldFeature) ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold) } else { ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0); } } } } }
Java
class StateContainer implements Consumer<WindowLayoutInfo> { @Override public void accept(WindowLayoutInfo newLayoutInfo) { // Add views that represent display features for (DisplayFeature displayFeature : newLayoutInfo.getDisplayFeatures()) { if (displayFeature instanceof FoldingFeature) { FoldingFeature foldFeature = (FoldingFeature)displayFeature; if (foldFeature.isSeparating() && foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL ) { // The foldable device is in tabletop mode int fold = foldPosition(motionLayout, foldFeature); ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold); } else { ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0); } } } } }
fireNewValue()
utilise un ID représentant la valeur en tant que premier paramètre.
la valeur à injecter en tant que deuxième paramètre.
ReactiveGuide
Une façon de profiter d'un SharedValue
dans une mise en page, sans avoir à
écrire du code, consiste à utiliser ReactiveGuide
. Cela permet de placer une ligne de référence horizontale ou verticale conformément aux
SharedValue
associé.
<androidx.constraintlayout.widget.ReactiveGuide
android:id="@+id/fold"
app:reactiveGuide_valueId="@id/fold"
android:orientation="horizontal" />
Vous pouvez ensuite l'utiliser comme vous le feriez normalement.
MotionLayout
pour les appareils pliables
Nous avons ajouté plusieurs fonctionnalités dans MotionLayout
dans la version 2.1 qui facilitent le morphing
particulièrement utile pour les appareils pliables,
gérer l'animation entre les
différentes mises en page possibles.
Deux approches sont disponibles pour les appareils pliables:
- Au moment de l'exécution, mettez à jour votre mise en page actuelle (
ConstraintSet
) pour afficher ou masquer la plier. - Utilisez un
ConstraintSet
distinct pour chacun des états de l'appareil pliable que vous souhaitez (closed
,folded
oufully open
).
Animer un ConstraintSet
La fonction updateStateAnimate()
dans MotionLayout
a été ajoutée à la version 2.1
sortie:
Kotlin
fun updateStateAnimate(stateId: Int, set: ConstraintSet, duration: Int)
Java
void updateStateAnimate(int stateId, ConstraintSet set, int duration);
Cette fonction animera automatiquement les modifications lors de la mise à jour d'une
ConstraintSet
au lieu d'effectuer une mise à jour immédiate (ce que vous pouvez faire avec
updateState(stateId, constraintset)
). Cela vous permet de mettre
à jour votre UI sur
en fonction des changements,
comme l'état de votre appareil pliable.
ReactiveGuide
à l'intérieur d'un MotionLayout
ReactiveGuide
prend également en charge deux attributs utiles lorsqu'il est utilisé dans un
MotionLayout
:
app:reactiveGuide_animateChange="true|false"
app:reactiveGuide_applyToAllConstraintSets="true|false"
Le premier modifiera le ConstraintSet
actuel et animera la modification
automatiquement. La seconde applique la nouvelle valeur de ReactiveGuide
à tous les ConstraintSet
dans MotionLayout
. Une approche typique pour
pour les pliables, il faudrait utiliser ReactiveGuide
pour représenter la position de pliage,
configurer vos éléments de mise en page par rapport à ReactiveGuide
.
Utiliser plusieurs éléments ConstraintSet
pour représenter l'état des appareils pliables
Au lieu de mettre à jour l'état MotionLayout
actuel, vous pouvez structurer
votre UI pour prendre en charge les appareils pliables consiste à créer des états distincts spécifiques (y compris
closed
, folded
et fully open
).
Dans ce scénario, vous pouvez toujours utiliser un ReactiveGuide
pour représenter le
mais vous bénéficiez d'un contrôle bien plus important
lors de la mise à jour du ConstraintSet
actuel) sur la façon dont chaque état
passer à un autre.
Avec cette approche, dans votre écouteur DeviceState
, vous dirigeriez simplement
MotionLayout
pour passer à des états spécifiques via la
MotionLayout.transitionToState(stateId)
.