1
votes

changer la largeur de la mise en page avec une animation dans Android

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


0 commentaires

3 Réponses :


0
votes

Essayez de mettre android: animateLayoutChanges = "true" sur la vue parente (XML). Plus d'informations: https://proandroiddev.com/the-little-secret-of- android-animatelayoutchanges-e4caab2fddec


0 commentaires

0
votes

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>


0 commentaires

1
votes

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

    li >
  • 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 () .


1 commentaires

Merci de votre réponse. C'était très utile