J'utilise la mise en page animée dans mon activité principale. Cela fonctionne correctement. Cependant, lorsque je passe à d'autres activités et que je reviens à mon activité principale, l'activité est parfois réinitialisée et la mise en page est dans son état de départ. Comment éviter que cela ne se produise? En dehors de cette J'ai également une autre question sur la disposition de mouvement que j'ai posée ici < / p>
4 Réponses :
Vous pouvez ajouter un écouteur de transition à la disposition de mouvement et enregistrer un indicateur lorsque la transition est terminée. Ensuite, lorsque l'activité est recréée, vous pouvez lire cet indicateur et l'utiliser comme suit:
motionLayout.setState (R.id.end, ConstraintSet.WRAP_CONTENT, ConstraintSet.WRAP_CONTENT)
Où R.id.end est l'identifiant de la propriété constraintSetEnd.
Je n'ai pas compris
Vous devez enregistrer / restaurer la progression de votre MotionLayout:
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putFloat("progress", motionLayout.progress) } override fun onCreate(savedInstanceState: Bundle?) { ... if (savedInstanceState != null) motionLayout.progress = savedInstanceState.getFloat("progress", 0f) ... }
class ExtMotionLayout : MotionLayout { constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) override fun onSaveInstanceState(): Parcelable? { return SavedState(progress, super.onSaveInstanceState()) } override fun onRestoreInstanceState(state: Parcelable?) { if (state is SavedState) { progress = state.progress super.onRestoreInstanceState(state.superState) } else super.onRestoreInstanceState(state) } class SavedState : BaseSavedState { val progress: Float constructor(progress: Float, source: Parcelable?) : super(source) { this.progress = progress } constructor(superState: Parcel) : super(superState) { progress = superState.readFloat() } override fun writeToParcel(out: Parcel, flags: Int) { super.writeToParcel(out, flags) out.writeFloat(progress) } } }
Ce que j'ai fait a été d'ajouter un champ, un champ booléen pour être précis et utiliser le cycle de vie pour le gérer.
private var hasMotionScrolled = false override fun onResume() { super.onResume() if (hasMotionScrolled) motionLayout.progress = MOTION_TRANSITION_COMPLETED } override fun onPause() { super.onPause() hasMotionScrolled = motionLayout.progress > MOTION_TRANSITION_INITIAL } companion object { private const val MOTION_TRANSITION_COMPLETED = 1F private const val MOTION_TRANSITION_INITIAL = 0F }
Donc dans mon cas, la mise en page animée fait une animation liée à défilement. Si ce n'est pas votre cas, vous pouvez peut-être utiliser directement le motionLayout.progress
. Mon problème avec l'utilisation directe de progress
était que les états intermédiaires rendraient les autres éléments invisibles lors de la navigation en arrière, c'est pourquoi j'ai implémenté un indicateur booléen tout ou rien.
Je ne le fais pas. voyez cela comme une solution propre, un drapeau est toujours quelque chose qui signifie que quelque chose d'autre aurait pu être mieux, si vous pouvez trouver quelque chose d'officiel, veuillez me le faire savoir dans les commentaires.
Seule solution de travail en combinaison avec NavigationComponents. Petite amélioration: n'oubliez pas de sauvegarder la variable dans onSaveInstanceState