Afficher et masquer une vue avec une animation de diapositive haut / bas

318

J'ai un LinearLayoutque je veux afficher ou masquer avec un Animationqui pousse la mise en page vers le haut ou vers le bas chaque fois que je change sa visibilité.

J'ai vu quelques échantillons mais aucun d'entre eux ne correspond à mes besoins.

J'ai créé deux fichiers xml pour les animations mais je ne sais pas comment les démarrer quand je change la visibilité d'un LinearLayout.

MichelReap
la source

Réponses:

640

Avec la nouvelle API d'animation introduite dans Android 3.0 (Honeycomb), il est très simple de créer de telles animations.

Faire glisser Viewvers le bas d'une distance:

view.animate().translationY(distance);

Vous pouvez ensuite faire glisser le Viewdos à sa position d'origine comme ceci:

view.animate().translationY(0);

Vous pouvez également combiner facilement plusieurs animations. L'animation suivante fera glisser un Viewvers le bas de sa hauteur et la fondra en même temps:

// Prepare the View for the animation
view.setVisibility(View.VISIBLE);
view.setAlpha(0.0f);

// Start the animation
view.animate()
    .translationY(view.getHeight())
    .alpha(1.0f)
    .setListener(null);

Vous pouvez ensuite estomper l' Viewarrière et le faire revenir à sa position d'origine. Nous avons également défini un AnimatorListenerafin que nous puissions définir la visibilité du Viewdos sur GONEune fois l'animation terminée:

view.animate()
    .translationY(0)
    .alpha(0.0f)
    .setListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            super.onAnimationEnd(animation);
            view.setVisibility(View.GONE);
        }
    });
Xaver Kapeller
la source
1
pourquoi la vue n'est pas visible une fois qu'elle a disparu?
Ram
1
je veux animer la vue lorsqu'elle est visible et lorsqu'elle est partie. mais si je suis parti pour la première fois. il ne peut pas être visible et le lieu de vue est vide
Ram
3
@Ram Qu'essayez-vous de réaliser en animant un Viewlorsque sa visibilité est définie sur View.GONE? Si vous définissez sa visibilité sur autre chose, View.VISIBLEle Viewne sera pas visible. Je ne comprends pas ce que vous demandez. Si vous voulez que votre animation soit visible alors ne définissez pas la visibilité du Viewà View.GONE.
Xaver Kapeller
2
face au même problème que celui auquel Ram était confronté, la première fois, cela fonctionne bien, mais la prochaine fois que je rendrai cette vue à l'état disparu et que j'essaierai de la rendre à nouveau visible, elle n'apparaît pas.
Pankaj kumar
12
@XaverKapeller Je pense que le problème est que beaucoup ont l'auditeur onAnimationEndest appelé à chaque fois pour une animation multi-produisant, ce qui signifie que l' onAnimationEndon appelle également lorsque la vue se montre, qui fixe sa visibilité Gone, etc.
oldergod
129

J'avais du mal à comprendre et à appliquer la réponse acceptée. J'avais besoin d'un peu plus de contexte. Maintenant que je l'ai compris, voici un exemple complet:

entrez la description de l'image ici

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Button myButton;
    View myView;
    boolean isUp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        myView = findViewById(R.id.my_view);
        myButton = findViewById(R.id.my_button);

        // initialize as invisible (could also do in xml)
        myView.setVisibility(View.INVISIBLE);
        myButton.setText("Slide up");
        isUp = false;
    }

    // slide the view from below itself to the current position
    public void slideUp(View view){
        view.setVisibility(View.VISIBLE);
        TranslateAnimation animate = new TranslateAnimation(
                0,                 // fromXDelta
                0,                 // toXDelta
                view.getHeight(),  // fromYDelta
                0);                // toYDelta
        animate.setDuration(500);
        animate.setFillAfter(true);
        view.startAnimation(animate);
    }

    // slide the view from its current position to below itself
    public void slideDown(View view){
        TranslateAnimation animate = new TranslateAnimation(
                0,                 // fromXDelta
                0,                 // toXDelta
                0,                 // fromYDelta
                view.getHeight()); // toYDelta
        animate.setDuration(500);
        animate.setFillAfter(true);
        view.startAnimation(animate);
    }

    public void onSlideViewButtonClick(View view) {
        if (isUp) {
            slideDown(myView);
            myButton.setText("Slide up");
        } else {
            slideUp(myView);
            myButton.setText("Slide down");
        }
        isUp = !isUp;
    }
}

activity_mail.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.slideview.MainActivity">

    <Button
        android:id="@+id/my_button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="100dp"
        android:onClick="onSlideViewButtonClick"
        android:layout_width="150dp"
        android:layout_height="wrap_content"/>

    <LinearLayout
        android:id="@+id/my_view"
        android:background="#a6e1aa"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="200dp">

    </LinearLayout>

</RelativeLayout>

Remarques

  • Merci à cet article de m'avoir pointé dans la bonne direction. C'était plus utile que les autres réponses sur cette page.
  • Si vous souhaitez commencer avec la vue à l'écran, ne l'initialisez pas en tant que INVISIBLE.
  • Étant donné que nous l'animons complètement hors écran, il n'est pas nécessaire de le rétablir INVISIBLE. Si vous n'animez pas complètement hors écran, vous pouvez ajouter une animation alpha et définir la visibilité avec un AnimatorListenerAdapter.
  • Documents d'animation de propriété
Suragch
la source
android: visibilité = "invisible" pour initialiser l'animation de la vue en tant que peau
Goodlife
2
Je ne recommande pas l'utilisation de animate.setFillAfter (true); si vous avez des vues cliquables sous la vue coulissante, il ne recevra pas d'événements
HOCiNE BEKKOUCHE
2
Notez que sans .setVisibility(View.INVISIBLE);la fonction glisser vers le haut ne fonctionnera pas comme prévu visuellement.
Advait S
Translate Animationdéplace la vue. Si vous souhaitez animer la vue comme sa mise à l'échelle elle-même, utilisezScaleAnimation anim = new ScaleAnimation(1, 1, 0, 1)
Zohab Ali
33

Maintenant, les animations de changement de visibilité doivent être effectuées via le Transition APImodule de support (androidx). Appelez simplement la méthode TransitionManager.beginDelayedTransition avec la transition Slide, puis changez la visibilité de la vue.

entrez la description de l'image ici

import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;

private void toggle(boolean show) {
    View redLayout = findViewById(R.id.redLayout);
    ViewGroup parent = findViewById(R.id.parent);

    Transition transition = new Slide(Gravity.BOTTOM);
    transition.setDuration(600);
    transition.addTarget(R.id.redLayout);

    TransitionManager.beginDelayedTransition(parent, transition);
    redLayout.setVisibility(show ? View.VISIBLE : View.GONE);
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="play" />

    <LinearLayout
        android:id="@+id/redLayout"
        android:layout_width="match_parent"
        android:layout_height="400dp"
        android:background="#5f00"
        android:layout_alignParentBottom="true" />
</RelativeLayout>

Vérifiez cette réponse avec un autre exemple de transition par défaut et personnalisé.

ashakirov
la source
@akubi ouais, ça devrait être
Aba
1
Une des réponses les meilleures et les plus faciles! Merci!
krisDrOid
juste pour noter, cela nécessiteminSdkVersion 21
lasec0203
@ lasec0203 non, les classes proviennent du androidxpackage. Cela fonctionne très bien sur la pré 21 api.
ashakirov
: thumbs_up: cela s'est débarrassé d'une erreur d'ambiguïté de méthode que j'obtenais
lasec0203
30

Solution la plus simple: placez-vous android:animateLayoutChanges="true"sur le conteneur contenant vos vues.

Pour le mettre dans un certain contexte: Si vous avez une disposition comme ci-dessous, toutes les modifications de visibilité des vues dans ce conteneur seront animées automatiquement.

<LinearLayout android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    >

    <Views_which_change_visibility>

</LinearLayout>

Vous pouvez trouver plus de détails à ce sujet dans Animation des changements de mise en page - Développeur Android

Stefan Medack
la source
C'est le plus simple mais son comportement diffère en raison du fabricant du téléphone et il a changé de code
b2mob
Cela anime l'alpha, pas la position.
Suragch
Oui, mais c'est de cela qu'il s'agissait à l'origine si j'ai bien compris. Si vous souhaitez animer des positions, vous pouvez utiliser un RecyclerView qui utilise ViewHolders avec des identifiants stables.
Stefan Medack du
12

Vous pouvez démarrer le correct Animationlorsque la visibilité des LinearLayoutmodifications en créant une nouvelle sous-classe de LinearLayoutet en remplaçant setVisibility()pour démarrer le Animations. Considérez quelque chose comme ceci:

public class SimpleViewAnimator extends LinearLayout
{
    private Animation inAnimation;
    private Animation outAnimation;

    public SimpleViewAnimator(Context context)
    {
        super(context);
    }

    public void setInAnimation(Animation inAnimation)
    {
        this.inAnimation = inAnimation;
    }

    public void setOutAnimation(Animation outAnimation)
    {
        this.outAnimation = outAnimation;
    }

    @Override
    public void setVisibility(int visibility)
    {
        if (getVisibility() != visibility)
        {
            if (visibility == VISIBLE)
            {
                if (inAnimation != null) startAnimation(inAnimation);
            }
            else if ((visibility == INVISIBLE) || (visibility == GONE))
            {
                if (outAnimation != null) startAnimation(outAnimation);
            }
        }

        super.setVisibility(visibility);
    }
}
Xaver Kapeller
la source
1
En fait, j'aime mieux l'approche de la sous-classe. Merci beaucoup.
MichelReap
1
C'est une solution géniale que je vais implémenter dans ma BaseView. Merci pour ça!
Bram Vandenbussche le
1
Comme cela fonctionne lors de l'affichage, lors du masquage, la vue disparaît avant que l'animation ne soit visible. Des solutions?
Bernardo
12
@BramVandenbussche C'est une terrible solution. Il rend le Viewresponsable de ses propres animations qui n'est JAMAIS ce que vous voulez. Imaginez que vous souhaitez animer le Viewdifféremment dans une autre partie de votre application. Que faites-vous alors? Ajouter un drapeau pour ne pas animer automatiquement la visibilité? Sous-classer le Viewet remplacer setVisibility()pour supprimer l'animation? Ou encore pire implémenter setVisibility()avec une autre animation? Cela devient de plus en plus laid à partir de là. N'utilisez pas cette "solution".
Xaver Kapeller
3
Mieux vaut l'appeler AnimatedLinearLayout
Roel
12

Kotlin

Sur la base de la réponse de Suragch , voici une manière élégante d'utiliser l'extension View:

fun View.slideUp(duration: Int = 500) {
    visibility = View.VISIBLE
    val animate = TranslateAnimation(0f, 0f, this.height.toFloat(), 0f)
    animate.duration = duration.toLong()
    animate.fillAfter = true
    this.startAnimation(animate)
}

fun View.slideDown(duration: Int = 500) {
    visibility = View.VISIBLE
    val animate = TranslateAnimation(0f, 0f, 0f, this.height.toFloat())
    animate.duration = duration.toLong()
    animate.fillAfter = true
    this.startAnimation(animate)
}

Et puis partout où vous voulez l' utiliser, vous avez juste besoin myView.slideUp()oumyView.slideDown()

Đorđe Nilović
la source
Seul bogue, il n'a pas besoin de "fillAfter = true" car il bloque les vues des enfants sur l'accessibilité des clics
Ranjan
De plus, vous devrez probablement ajouter un écouteur à l'animation slideDown et faire disparaître la vue surAnimationEnd.
Manohar Reddy
9
if (filter_section.getVisibility() == View.GONE) {
    filter_section.animate()
            .translationY(filter_section.getHeight()).alpha(1.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    super.onAnimationStart(animation);
                    filter_section.setVisibility(View.VISIBLE);
                    filter_section.setAlpha(0.0f);
                }
            });
} else {
    filter_section.animate()
            .translationY(0).alpha(0.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    filter_section.setVisibility(View.GONE);
                }
            });
}
Ameen Maheen
la source
10
Problèmes avec cette réponse: 1) Formatage de code terrible. 2) Vous utilisez un extrait de code pour publier du code qui ne peut pas être exécuté dans le navigateur. Cela n'ajoute pas seulement deux boutons inutiles, mais détruit également la coloration syntaxique. 3) C'est juste un vidage de code aléatoire sans explication ni but. 4) Vous modifiez la visibilité lors de l'exécution d'une animation. Mis à part le fait que c'est une odeur de code évidente, cela ne fonctionnera pas non plus correctement. La modification de la visibilité démarre un nouveau processus de mise en page, mais une fois terminé, l'animation a réellement des valeurs à utiliser. La liste s'allonge encore et encore ...
Xaver Kapeller
J'ai déjà modifié votre réponse pour corriger la mise en forme et transformé l'extrait de code en un véritable bloc de code. Mais vous devez remplir le reste ...
Xaver Kapeller
Désolé, je l'ai copié, j'ai créé le code à partir du vôtre parce qu'il ne fonctionne pas bien pour moi, ce code fonctionne, mais des changements nécessaires dans la manière de publier, je suis d'accord.
Ameen Maheen
@AmeenMaheen À quoi ça sert setAlpha?
IgorGanapolsky
@ Igor Ganapolsky, il est utilisé pour la transparence, c'est-à-dire pour donner un effet de décoloration
Ameen Maheen
4

vous pouvez faire glisser n'importe quelle vue ou disposition en utilisant le code ci-dessous dans l'application Android

boolean isClicked=false;
LinearLayout mLayoutTab = (LinearLayout)findViewById(R.id.linearlayout);

        if(isClicked){
                    isClicked = false;
                    mLayoutTab.animate()
                    .translationYBy(120)
                    .translationY(0)     
                    .setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));

        }else{
                isClicked = true;
                mLayoutTab.animate()
                .translationYBy(0)
                .translationY(120)
                .setDuration(getResources().getInteger(android.R.integer.config_mediumAnimTime));
                }
varotariya vajsi
la source
qu'est-ce que 120? et qu'est-ce que 0? quelle est l'unité pour setDuration si je veux coder en dur cela?
stanley santoso
1
ici 120 et 0 est la distance liée à l'axe Y si vous mettez du code dur plutôt que d'avoir un problème sur un grand écran ou une tablette, vous devez donc mettre la valeur de votre valeur string.xml pour tous les différents appareils. et la durée est le temps que vous souhaitez afficher l'animation de la mise en page .... !!! Désolé pour mon mauvais anglais...!
varotariya vajsi
@varotariyavajsi Cela n'affiche pas / masque la visibilité d'une vue.
IgorGanapolsky
bonjour igor ganapolsky je les connais ... il suffit de traduire la vue dans la direction y, si l'utilisateur a besoin de se montrer de haut en bas comme un curseur inférieur, cela fonctionnera bien.
varotariya vajsi
4

Utilisez cette classe:

public class ExpandCollapseExtention {

 public static void expand(View view) {
    view.setVisibility(View.VISIBLE);

    final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    view.measure(widthSpec, heightSpec);

    ValueAnimator mAnimator = slideAnimator(view, 0, view.getMeasuredHeight());
    mAnimator.start();
}


public static void collapse(final View view) {
    int finalHeight = view.getHeight();

    ValueAnimator mAnimator = slideAnimator(view, finalHeight, 0);

    mAnimator.addListener(new Animator.AnimatorListener() {

        @Override
        public void onAnimationEnd(Animator animator) {               
            view.setVisibility(View.GONE);
        }


        @Override
        public void onAnimationStart(Animator animation) {

        }


        @Override
        public void onAnimationCancel(Animator animation) {

        }


        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });
    mAnimator.start();
}


private static ValueAnimator slideAnimator(final View v, int start, int end) {

    ValueAnimator animator = ValueAnimator.ofInt(start, end);

    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {

            int value = (Integer) valueAnimator.getAnimatedValue();
            ViewGroup.LayoutParams layoutParams = v.getLayoutParams();
            layoutParams.height = value;
            v.setLayoutParams(layoutParams);
        }
    });
    return animator;
}
}
amin
la source
3

Utilisation d'ObjectAnimator

private fun slideDown(view: View) {
    val height = view.height
    ObjectAnimator.ofFloat(view, "translationY", 0.toFloat(), height.toFloat()).apply {
        duration = 1000
        start()
    }
}

private fun slideUp(view: View) {
    val height = view.height
    ObjectAnimator.ofFloat(view, "translationY", height.toFloat(),0.toFloat()).apply {
        duration = 1000
        start()
    }
}
Vihaan Verma
la source
2
Améliorations mineures: nous pouvons utiliser View.TRANSLATION_Y constant au lieu de "translationY" et également dans la diapositive ObjectAnimation nous pouvons faire .apply {doOnEnd {view.visibility = View.GONE} .......}. Start ()
tashi
0.toFloat()peut aussi être simplement0f
styler1972
2

J'avais un cas d'angle où la hauteur de ma vue était toujours zerosi ...

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;

public final class AnimationUtils {

  public static void slideDown(final View view) {
        view.animate()
                .translationY(view.getHeight())
                .alpha(0.f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        // superfluous restoration
                        view.setVisibility(View.GONE);
                        view.setAlpha(1.f);
                        view.setTranslationY(0.f);
                    }
                });
    }

    public static void slideUp(final View view) {
        view.setVisibility(View.VISIBLE);
        view.setAlpha(0.f);

        if (view.getHeight() > 0) {
            slideUpNow(view);
        } else {
            // wait till height is measured
            view.post(new Runnable() {
                @Override
                public void run() {
                    slideUpNow(view);
                }
            });
        }
    }

    private static void slideUpNow(final View view) {
        view.setTranslationY(view.getHeight());
        view.animate()
                .translationY(0)
                .alpha(1.f)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        view.setVisibility(View.VISIBLE);
                        view.setAlpha(1.f);
                    }
                });
    }

}
Samuel
la source
1

Voici ma solution. Obtenez simplement une référence à votre vue et appelez cette méthode:

public static void animateViewFromBottomToTop(final View view){

    view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {

            view.getViewTreeObserver().removeOnGlobalLayoutListener(this);

            final int TRANSLATION_Y = view.getHeight();
            view.setTranslationY(TRANSLATION_Y);
            view.setVisibility(View.GONE);
            view.animate()
                .translationYBy(-TRANSLATION_Y)
                .setDuration(500)
                .setStartDelay(200)
                .setListener(new AnimatorListenerAdapter() {

                    @Override
                    public void onAnimationStart(final Animator animation) {

                        view.setVisibility(View.VISIBLE);
                    }
                })
                .start();
        }
    });
}

Pas besoin de faire autre chose =)

Tiago
la source
1
Pourquoi auriez-vous besoin d'un GlobalLayoutListener pour ce faire? Pourquoi définissez-vous la visibilité d'une manière si étrange? Pourquoi incluez-vous des choses comme un retard de démarrage qui n'est pas pertinent à remettre en question dans votre réponse?
Xaver Kapeller
1

Réponse de Suragch dans Kotlin. Cela a fonctionné pour moi.

class MainActivity : AppCompatActivity() {

var isUp: Boolean = false

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var myView: View = findViewById(R.id.my_view)
    var myButton: Button = findViewById(R.id.my_button)

    //Initialize as invisible
    myView.visibility = View.INVISIBLE
    myButton.setText("Slide up")

    isUp = false

}


fun View.slideUp(duration: Int = 500){
    visibility = View.VISIBLE
    val animate = TranslateAnimation(0f, 0f, this.height.toFloat(), 0f)
    animate.duration = duration.toLong()
    animate.fillAfter = true
    this.startAnimation(animate)
}

fun View.slideDown(duration: Int = 500) {
    visibility = View.VISIBLE
    val animate = TranslateAnimation(0f, 0f, 0f, this.height.toFloat())
    animate.duration = duration.toLong()
    animate.fillAfter = true
    this.startAnimation(animate)
}

fun onSlideViewButtonClick(view: View){
    if(isUp){
        my_view.slideDown()
        my_button.setText("Slide Up")

    }
    else{
        my_view.slideUp()
        my_button.setText("Slide Down")
    }
    isUp = !isUp
}

}

olle
la source
0

Vous pouvez utiliser les trois simples lignes de code pour afficher l'animation ...

//getting the hiding view by animation

 mbinding.butn.setOnClickListener {

                val SlideOutLeft = AnimationUtils.loadAnimation(this, R.anim.slide_out_left)
                simplelayout.visibility = View.INVISIBLE
                simplelayout.startAnimation(SlideOutLeft)


                val SlideInRight = AnimationUtils.loadAnimation(applicationContext, R.anim.slide_in_right)
                animation1.visibility = View.VISIBLE
                animation1.startAnimation(SlideInRight)

            }
            //again unhide the view animation
            mbinding.buttn.setOnClickListener {


               val SlideInLeft=AnimationUtils.loadAnimation(this,R.anim.slide_in_left)
                //set the layout
               simplelayout.visibility=View.VISIBLE
               simplelayout.startAnimation(SlideInLeft)

               val SlideOutRight=AnimationUtils.loadAnimation(this,R.anim.slide_out_right)
               animation1.visibility=View.INVISIBLE
               animation1.startAnimation(SlideOutRight)

            }
Yogesh singh Pathania
la source
0

Avec les extensions Kotlin, vous pouvez utiliser ceci:

enum class SlideDirection{
    UP,
    DOWN,
    LEFT,
    RIGHT
}

enum class SlideType{
    SHOW,
    HIDE
}

fun View.slideAnimation(direction: SlideDirection, type: SlideType, duration: Long = 250){
    val fromX: Float
    val toX: Float
    val fromY: Float
    val toY: Float
    val array = IntArray(2)
    getLocationInWindow(array)
    if((type == SlideType.HIDE && (direction == SlideDirection.RIGHT || direction == SlideDirection.DOWN)) ||
        (type == SlideType.SHOW && (direction == SlideDirection.LEFT || direction == SlideDirection.UP))   ){
        val displayMetrics = DisplayMetrics()
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        val deviceWidth = displayMetrics.widthPixels
        val deviceHeight = displayMetrics.heightPixels
        array[0] = deviceWidth
        array[1] = deviceHeight
    }
    when (direction) {
        SlideDirection.UP -> {
            fromX = 0f
            toX = 0f
            fromY = if(type == SlideType.HIDE) 0f else (array[1] + height).toFloat()
            toY = if(type == SlideType.HIDE) -1f * (array[1] + height)  else 0f
        }
        SlideDirection.DOWN -> {
            fromX = 0f
            toX = 0f
            fromY = if(type == SlideType.HIDE) 0f else -1f * (array[1] + height)
            toY = if(type == SlideType.HIDE) 1f * (array[1] + height)  else 0f
        }
        SlideDirection.LEFT -> {
            fromX = if(type == SlideType.HIDE) 0f else 1f * (array[0] + width)
            toX = if(type == SlideType.HIDE) -1f * (array[0] + width) else 0f
            fromY = 0f
            toY = 0f
        }
        SlideDirection.RIGHT -> {
            fromX = if(type == SlideType.HIDE) 0f else -1f * (array[0] + width)
            toX = if(type == SlideType.HIDE) 1f * (array[0] + width) else 0f
            fromY = 0f
            toY = 0f
        }
    }
    val animate = TranslateAnimation(
        fromX,
        toX,
        fromY,
        toY
    )
    animate.duration = duration
    animate.setAnimationListener(object: Animation.AnimationListener{
        override fun onAnimationRepeat(animation: Animation?) {

        }

        override fun onAnimationEnd(animation: Animation?) {
            if(type == SlideType.HIDE){
                visibility = View.INVISIBLE
            }
        }

        override fun onAnimationStart(animation: Animation?) {
            visibility = View.VISIBLE
        }

    })
    startAnimation(animate)
}

Exemple pour l'extension:

view.slideAnimation(SlideDirection.UP, SlideType.HIDE)//to make it disappear through top of the screen
view.slideAnimation(SlideDirection.DOWN, SlideType.SHOW)//to make it reappear from top of the screen

view.slideAnimation(SlideDirection.DOWN, SlideType.HIDE)//to make it disappear through bottom of the screen
view.slideAnimation(SlideDirection.UP, SlideType.SHOW)//to make it reappear from bottom of the screen
Mertcan Çüçen
la source
0

Un des moyens simples:

containerView.setLayoutTransition(LayoutTransition())
containerView.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
hallz12
la source