Mostrar e ocultar uma vista com uma animação deslizante para cima / baixo

318

Eu tenho um LinearLayoutque eu quero mostrar ou ocultar com umAnimation que empurre o layout para cima ou para baixo sempre que alterar sua visibilidade.

Eu já vi algumas amostras por aí, mas nenhuma delas atende às minhas necessidades.

Criei dois arquivos xml para as animações, mas não sei como iniciá-los quando altero a visibilidade de a LinearLayout.

MichelReap
fonte

Respostas:

639

Com a nova API de animação que foi introduzida no Android 3.0 (Honeycomb), é muito simples criar essas animações.

Deslizando para Viewbaixo a uma distância:

view.animate().translationY(distance);

Posteriormente, você pode deslizar a Viewparte de trás para sua posição original assim:

view.animate().translationY(0);

Você também pode combinar facilmente várias animações. A animação a seguir deslizará um Viewpor sua altura e diminuirá ao mesmo tempo:

// 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);

Você pode desbotar a Viewparte traseira e deslizá-la de volta à sua posição original. Também definimos um AnimatorListenerpara que possamos definir a visibilidade das Viewcostas GONEquando a animação terminar:

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
fonte
1
por que ver não visível depois que se foi?
Ram
1
Eu quero animar a visualização quando visível e ausente. mas se eu primeira vista gone não .it capaz de visível e local de vista é em branco
Ram
3
@Ram O que você está tentando alcançar animando um Viewquando sua visibilidade está definida View.GONE? Se você definir sua visibilidade para algo além disso View.VISIBLE, o Viewitem não será visível. Eu não entendo o que você está perguntando. Se você deseja que sua animação seja visível, não defina a visibilidade de Viewpara View.GONE.
Xaver Kapeller
2
enfrentando o mesmo problema que o Ram estava enfrentando, na primeira vez ele funciona bem, mas a partir da próxima vez em que eu fizer essa visualização em estado morto e tentar torná-la visível novamente, ela não aparecerá.
Pankaj Kumar
12
@XaverKapeller Acho que o problema que muitos têm é que o ouvinte onAnimationEndé chamado todas as vezes para uma animação de várias ocorrências, o que significa que onAnimationEndtambém é chamado quando a exibição é exibida, o que define sua visibilidade como Gone etc.
oldergod
129

Eu estava tendo problemas para entender e aplicar a resposta aceita. Eu precisava de um pouco mais de contexto. Agora que eu descobri, aqui está um exemplo completo:

insira a descrição da imagem aqui

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>

Notas

  • Obrigado a este artigo por me indicar a direção certa. Foi mais útil do que as outras respostas nesta página.
  • Se você deseja começar com a exibição na tela, não a inicialize como INVISIBLE.
  • Como a animamos completamente fora da tela, não há necessidade de configurá-la novamente INVISIBLE. Se você não estiver animando completamente fora da tela, poderá adicionar uma animação alfa e definir a visibilidade com um AnimatorListenerAdapter.
  • Documentos de Animação de propriedade
Suragch
fonte
android: visibilidade = "invisível" para inicializar a animação vista como uma pele
Goodlife
2
Eu não recomendo o uso de animate.setFillAfter (true); se você tiver visualizações clicáveis ​​na visualização deslizada, ela não receberá eventos
HOCiNE BEKKOUCHE
2
Observe que sem .setVisibility(View.INVISIBLE);a função deslizar para cima não funcionará como o esperado visualmente.
Advait S
Translate Animationmove a vista. Se você deseja animar a visualização como se ela ScaleAnimation anim = new ScaleAnimation(1, 1, 0, 1)
fosse
33

Agora, as animações de alteração de visibilidade devem ser feitas através das Transition APIquais estão disponíveis no pacote de suporte (androidx). Basta chamar o método TransitionManager.beginDelayedTransition com transição de slides e alterar a visibilidade da exibição.

insira a descrição da imagem aqui

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>

Verifique esta resposta com outros exemplos de transição padrão e personalizados.

ashakirov
fonte
@akubi sim, deveria ser
Aba
1
Uma das melhores e fáceis respostas! Obrigado!
krisDrOid 29/02
apenas para observar, isso requerminSdkVersion 21
lasec0203 10/04
@ lasec0203 não, as classes são do androidxpacote. Funciona bem em pré 21 API.
ashakirov 10/04
: thumbs_up: isso se livrou de um erro de ambiguidade de método que eu estava recebendo
lasec0203 11/04
30

Solução mais fácil: definir android:animateLayoutChanges="true" no contêiner com suas opiniões.

Para colocar em algum contexto: Se você tiver um layout como abaixo, todas as alterações de visibilidade nas visualizações neste contêiner serão animadas automaticamente.

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

    <Views_which_change_visibility>

</LinearLayout>

Você pode encontrar mais detalhes sobre isso em Animating Changes Changes - Desenvolvedor Android

Stefan Medack
fonte
Ele é o mais fácil, mas é comportamento difere devido a fabricante do telefone e ele é alterações no código
b2mob
Isso anima o alfa, não a posição.
Suragch 10/10
Sim, mas era disso que se tratava a pergunta original, se eu a entendi corretamente. Se você deseja animar posições, você pode usar um RecyclerView que usa ViewHolders com IDs estáveis.
Stefan Medack 12/10
12

Você pode iniciar o correto Animationquando a visibilidade das LinearLayoutalterações for criar uma nova subclasse LinearLayoute substituir setVisibility()para iniciar o Animations. Considere algo como isto:

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
fonte
1
Na verdade, eu gosto mais da abordagem da subclasse. Muito obrigado.
perfil completo de MichelReap
1
Essa é uma solução incrível que vou implementar no meu BaseView. Thx por isso!
Bram Vandenbussche
1
Como isso funciona ao mostrar, ao ocultar, a vista desaparece antes que a animação possa ser vista. Alguma solução alternativa?
287 Bernardo
12
@BramVandenbussche Esta é uma solução terrível. Torna o Viewresponsável por suas próprias animações, que NUNCA é o que você deseja. Imagine que você deseja animar o Viewdiferente em outra parte do seu aplicativo. O que fazes, então? Adicionar um sinalizador para não animar automaticamente a visibilidade? Subclassar Viewe substituir setVisibility()para remover a animação? Ou ainda pior implementar setVisibility()com outra animação? Apenas fica cada vez mais feio a partir daí. Não use esta "solução".
Xaver Kapeller
3
Melhor chamá-lo de AnimatedLinearLayout
Roel
12

Kotlin

Baseado em Suragch 's resposta , aqui é uma maneira elegante usando Ver extensão:

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)
}

E então, onde você quiser usá-lo, você só precisa myView.slideUp()oumyView.slideDown()

Đorđe Nilović
fonte
Apenas bug é, ele não precisa "fillAfter = true", uma vez que bloquear a vista da criança clique acessibilidade
Ranjan
Além disso, você provavelmente precisará adicionar um ouvinte à animação slideDown e tornar a exibição emAnimationEnd.
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
fonte
10
Problemas com esta resposta: 1) Formatação de código terrível. 2) Você usa um trecho de código para postar um código que realmente não pode ser executado no navegador. Isso não apenas adiciona dois botões inúteis, mas também destrói o destaque da sintaxe. 3) É apenas um despejo aleatório de código sem nenhuma explicação ou objetivo. 4) Você está alterando a visibilidade enquanto executa uma animação. Além do fato de que esse é um código óbvio, isso também não funcionará corretamente. A alteração da visibilidade inicia um novo processo de layout, somente depois que a animação é finalizada, os valores realmente precisam ser trabalhados. A lista vai sobre e sobre ...
Xaver Kapeller
Já editei sua resposta para corrigir a formatação e transformei o trecho de código em um bloco de código real. Mas você tem que preencher o resto ...
Xaver Kapeller
Desculpe entendi, eu criei o código a partir do seu, porque ele não funciona bem para mim, este código meu funciona. Mas as alterações necessárias na maneira de postar eu concordo.
Ameen Maheen
@AmeenMaheen Para que serve setAlpha?
IgorGanapolsky
@ Igor Ganapolsky ele é usado para a transparência ou seja, para dar um efeito de desvanecimento
Ameen Maheen
4

você pode deslizar para cima e para baixo em qualquer visualização ou layout usando o código abaixo no aplicativo 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
fonte
o que é 120? e o que é 0? qual é a unidade para setDuration se eu quiser codificar isso?
Stanley santoso 29/08/2015
1
aqui 120 e 0 é a distância relacionada ao eixo Y, se você colocar o código rígido em vez de obter problemas na tela grande ou no tablet, será necessário adicionar valor do valor string.xml para todos os dispositivos diferentes. e duração é o tempo que você deseja mostrar a animação do layout .... !!! desculpe pelo meu pobre inglês ...!
varotariya vajsi 8/09/15
@varotariyavajsi Na verdade, isso não mostra / oculta a visibilidade de uma exibição.
IgorGanapolsky
Olá igor ganapolsky eu conheço estes ... é apenas traduzir a visualização na direção y, se o usuário precisar aparecer para cima e para baixo como um controle deslizante inferior, ele estará funcionando bem.
varotariya vajsi 15/09/2015
4

Use esta 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
fonte
3

Usando 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
fonte
2
Pequenas melhorias: podemos usar View.TRANSLATION_Y constante em vez de "translationY" e também no slide acima ObjectAnimation, podemos fazer .apply {doOnEnd {view.visibility = View.GONE} .......}. Start ()
tashi 27/03
0.toFloat()também pode ser apenas0f
styler1972
2

Eu tinha uma caixa de canto onde a altura da minha vista ainda era zerotão ...

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
fonte
1

Aqui está a minha solução. Basta obter uma referência à sua visualização e chamar este método:

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();
        }
    });
}

Não há necessidade de fazer mais nada =)

Tiago
fonte
1
Por que você precisaria de um GlobalLayoutListener para fazer isso? Por que você está definindo a visibilidade de uma maneira tão estranha? Por que você está incluindo coisas como um atraso de início que é irrelevante para ser questionado em sua resposta?
Xaver Kapeller
1

Resposta de Suragch em Kotlin. Isso funcionou para mim.

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
fonte
0

Você pode usar as três linhas de código simples para mostrar a animação ...

//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
fonte
0

Com as extensões Kotlin, você pode usar isto:

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)
}

Exemplo para a extensão:

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
fonte
0

Uma das maneiras simples:

containerView.setLayoutTransition(LayoutTransition())
containerView.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
hallz12
fonte