J'essaye de changer ma largeur relativeLayout avec animation.Mon objectif est de changer la largeur WRAP_CONTENT en MATCH_PARENT avec animation.Voici mon code source
if (isKeyBoardOpen) setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); else setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
J'appelle cette méthode comme ceci
private void setWidthAnimation(View view, int currentHeight, int newHeight) { ValueAnimator slideAnimator = ValueAnimator .ofInt(currentHeight, newHeight) .setDuration(1000); slideAnimator.addUpdateListener(animation -> { Integer value = (Integer) animation.getAnimatedValue(); view.getLayoutParams().width = value.intValue(); view.requestLayout(); }); AnimatorSet set = new AnimatorSet(); set.play(slideAnimator); set.setInterpolator(new BounceInterpolator()); set.start(); view.setBackgroundColor(Color.RED); }
Mais lorsque j'exécute mon application, la largeur de la vue a changé mais sans animation. quelqu'un peut-il m'expliquer ce que je fais mal? Merci
3 Réponses :
Essayez de mettre android: animateLayoutChanges = "true"
sur la vue parente (XML).
Plus d'informations:
https://proandroiddev.com/the-little-secret-of- android-animatelayoutchanges-e4caab2fddec
Je ne sais vraiment pas quoi avec votre code, mais je peux vous suggérer mon option: mettre votre parent dans Constraint et travailler avec une animation de jeu de contraintes. Démarrer xml
RelativeLayout layout; ConstraintLayout root; ... layout = findViewById(R.id.rLayout); root = findViewById(R.id.rootContainer); public void animate() { ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(0, 0); layout.setLayoutParams(params); ConstraintSet set = new ConstraintSet(); set.clone(root); set.connect(layout.getId(), ConstraintSet.BOTTOM, root.getId(), ConstraintSet.BOTTOM); set.connect(layout.getId(), ConstraintSet.TOP, root.getId(), ConstraintSet.TOP); set.connect(layout.getId(), ConstraintSet.LEFT, root.getId(), ConstraintSet.LEFT); set.connect(layout.getId(), ConstraintSet.RIGHT, root.getId(), ConstraintSet.RIGHT); AutoTransition transition = new AutoTransition(); transition.setDuration(1000); TransitionManager.beginDelayedTransition(root, transition); set.applyTo(root); }
Et code:
<android.support.constraint.ConstraintLayout 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="match_parent" android:id="@+id/rootContainer" tools:context=".MainActivity"> <RelativeLayout android:id="@+id/rLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorAccent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </RelativeLayout>
Le principal problème de votre code est que vous n'avez pas réellement les valeurs réelles de la largeur.
Si vous regardez votre méthode setWidthAnimation ()
, regardez où elle dit:
setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
En particulier, regardez currentHeight et newHeight . Savez-vous quelles sont les valeurs de ces deux variables int?
ValueAnimator slideAnimator = ValueAnimator .ofInt(currentHeight, newHeight) .setDuration(1000);
Vous utilisez ViewGroup.LayoutParams.WRAP_CONTENT
et ViewGroup. LayoutParams.MATCH_PARENT
comme valeurs pour la largeur. Cependant, ni l'un ni l'autre ne correspondent à la largeur réelle de votre vue.
Au lieu de cela, ce ne sont que des constantes statiques de LayoutParams
:
MATCH_PARENT
est une constante statique int avec une valeur de -1
WRAP_CONTENT
est une constante statique int avec une valeur de -2
Donc, vous dites essentiellement à ValueAnimator d'animer de la valeur de -1 à -2 ou -2 à -1 en une durée de 1 seconde.
De plus, vous définissez simplement -1 ou -2 à la largeur du LayoutParam. Heureusement pour vous, cela permet d'obtenir l'apparence terminée de votre vue, car la largeur d'une vue peut avoir 3 types de possibilités:
layoutParams.width = -1; Cela revient à appeler FILL_PARENT
ou MATCH_PARENT
layoutParams.width = -2; Cela revient à appeler WRAP_CONTENT
layoutParams.width = ANY_OTHER_INT; Cela revient à définir directement la largeur sur cette valeur.
Cependant, aucune animation ne se produira.
La raison en est simplement que ValueAnimator n'effectue aucune animation. Vous pouvez le considérer davantage comme un compteur numérique. Vous l'avez codé pour compter les valeurs int de -1 à -2 sur une période de 1 seconde. Alors quand ça commence, c'est à WRAP_CONTENT
. La prochaine valeur int possible est -2, qui est la valeur finale, donc elle sera mise à jour exactement après 1 seconde. Une seconde plus tard, il met à jour et exécute le code que vous avez qui définit la largeur de la vue sur -2. Cela force instantanément la vue à être MATCH_PARENT
.
Donc, pour résoudre ce problème, vous devez passer les valeurs entières réelles à votre méthode setWidthAnimation ()
.
Merci de votre réponse. C'était très utile