用上下滑动动画显示和隐藏视图

我有一个LinearLayout,我想用一个Animation来显示或隐藏它,当我改变它的可见性时,它会向上或向下推布局。

我在那里看过一些样品,但没有一个适合我的需要。

我已经为动画创建了两个xml文件,但我不知道当我改变LinearLayout的可见性时如何启动它们。

468060 次浏览

随着Android 3.0 (Honeycomb)引入的新动画API,创建这样的动画非常简单。

向下滑动View一段距离:

view.animate().translationY(distance);

稍后你可以像这样将View滑动回它原来的位置:

view.animate().translationY(0);

您还可以轻松地组合多个动画。下面的动画会将View向下滑动其高度并同时将其淡入:

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

然后,您可以将View淡出并将其滑回原始位置。我们还设置了AnimatorListener,以便在动画完成后将View的可见性设置回GONE:

view.animate()
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});

LinearLayout的可见性发生变化时,可以通过创建LinearLayout的新子类并覆盖setVisibility()来启动Animations来启动正确的Animation。考虑一下这样的事情:

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

你可以上下滑动任何视图或布局使用咆哮的代码在安卓应用程序

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

这是我的解决方案。只需要获取视图的引用并调用这个方法:

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

不需要做任何其他事情=)

最简单的解决方案:在保存视图的容器上设置android:animateLayoutChanges="true"

如果你有一个如下所示的布局,这个容器中所有视图的可见性变化都将自动动画化。

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


<Views_which_change_visibility>


</LinearLayout>

你可以在动画布局变化- Android开发者上找到更多的细节

使用这个类:

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

我有一个角落的情况,我的视图的高度仍然是zero,所以…

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


}

我在理解和应用公认的答案时遇到了困难。我需要更多的背景知识。现在我已经搞清楚了,下面是一个完整的例子:

enter image description here

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>

笔记

  • 感谢这篇文章为我指明了正确的方向。它比本页上的其他答案更有帮助。
  • 如果你想从屏幕上的视图开始,那么不要将它初始化为INVISIBLE
  • 因为我们是完全在屏幕外制作动画,所以没有必要将它设置回INVISIBLE。如果你不是完全在屏幕外动画,那么你可以添加一个alpha动画,并使用AnimatorListenerAdapter设置可见性。
  • 属性动画文档

芬兰湾的科特林

基于Suragch回答,下面是一种使用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)
}

然后无论你想在哪里使用它,你只需要myView.slideUp()myView.slideDown()

Suragch用科特林语回答。这对我很管用。

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
}

现在可见性变化动画应该通过Transition API来完成,这在支持(androidx)包中可用。只需使用幻灯片转换调用TransitionManager.beginDelayedTransition方法,然后更改视图的可见性。

enter image description here

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>

用另一个默认和自定义转换示例检查这个答案

你可以使用简单的三行代码来显示动画…

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


}

使用ObjectAnimator

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


private fun slideUp(view: View) {
val height = view.height
ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, height.toFloat(), 0f)).apply {
duration = 1000
start()
}
}

通过Kotlin扩展,你可以这样使用:

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

扩展示例:

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

其中一个简单的方法是:

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

这里有另一种方法来处理多个Button(在本例中是ImageView)

MainActivity.java

findViewById(R.id.arrowIV).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {


if (strokeWidthIV.getAlpha() == 0f) {
findViewById(R.id.arrowIV).animate().rotationBy(180);


strokeWidthIV.animate().translationXBy(-120 * 4).alpha(1f);
findViewById(R.id.colorChooseIV).animate().translationXBy(-120 * 3).alpha(1f);
findViewById(R.id.saveIV).animate().translationXBy(-120 * 2).alpha(1f);
findViewById(R.id.clearAllIV).animate().translationXBy(-120).alpha(1f);
} else {
findViewById(R.id.arrowIV).animate().rotationBy(180);


strokeWidthIV.animate().translationXBy(120 * 4).alpha(0f);
findViewById(R.id.colorChooseIV).animate().translationXBy(120 * 3).alpha(0f);
findViewById(R.id.saveIV).animate().translationXBy(120 * 2).alpha(0f);
findViewById(R.id.clearAllIV).animate().translationXBy(120).alpha(0f);
}
}
});


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".activity.MainActivity">


<ImageView
android:id="@+id/strokeWidthIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_edit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />


<ImageView
android:id="@+id/colorChooseIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_palette"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />


<ImageView
android:id="@+id/saveIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_save"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />


<ImageView
android:id="@+id/clearAllIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:alpha="0"
android:contentDescription="Clear All"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_clear_all"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />


<ImageView
android:id="@+id/arrowIV"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:contentDescription="Arrow"
android:padding="4dp"
android:scaleType="fitXY"
android:src="@drawable/ic_arrow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>

一个完整的答案,在onClick中切换视图可见性,也翻转箭头,并在隐藏组件时平滑地向上移动其他视图。

private fun toggleRecyclerViewVisibility(
recyclerView: RecyclerView,
container: FrameLayout,
arrow: ImageView
) {
//toggle arrow direction, also block user clicks until animation finishes.
arrow
.animate()
.rotation(
if (arrow.rotation == 0F)
180F
else 0F
)
.withStartAction { container.isClickable = false }
.withEndAction { container.isClickable = true }
.start()


//toggle recyclerview visibility with animation.
with(recyclerView) {
var cof = -1
var vis = View.GONE
var alph = 0F


if (visibility == View.GONE) {
cof = 0
vis = View.VISIBLE
alph = 1F
}
animate()
.translationY(height.toFloat() * cof)
.alpha(alph)
.withStartAction {//in case showing the recyclerview show it at the beginning.
if (vis == View.VISIBLE)
visibility = View.VISIBLE
}
.withEndAction {//in case hiding the recyclerview hide it at the end.
if (vis == View.GONE)
visibility = View.GONE
}
.start()
}
}

视图是这样的

        <LinearLayout
android:id="@+id/subRootLinearView"
android:animateLayoutChanges="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">


<!--other views-->
<LinearLayout
android:id="@+id/Container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">


<FrameLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/backgroundGray"
android:padding="16dp">


<TextView
android:id="@+id/text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/awaitingConfirmation"
android:textColor="@color/colorText"
android:textSize="16sp" />


<ImageView
android:id="@+id/arrow_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center"
android:src="@drawable/ic_arrow" />
</FrameLayout>


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">


<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>


<!--other views-->
</LinearLayout>

然后在代码中首先添加这一行,这解决了animateLayoutChanges不能在大嵌套视图中工作的问题,这基本上使其他视图在隐藏recyclerview时平滑地向上移动

subRootLinearView.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)

你的父线性布局也应该包含这个属性

android:animateLayoutChanges="true"

然后用视图调用该方法

 toggleRecyclerViewVisibility(
recycler,
header,
arrowImageView
)

芬兰湾的科特林用户的ashakirov的答案

 val transition: Transition = Slide(Gravity.BOTTOM)
transition.duration = 600
transition.addTarget(you_parent_layout_id)
TransitionManager.beginDelayedTransition(rootLayoutId, transition)
yourViewIdToHide.visibility = if (yourViewIdToHide.isShown) View.GONE else View.VISIBLE

如果你想和Transition一起显示/隐藏多个视图,你可以使用TransitionSet(因为你不能播放2 "单"Transition一起)

fun slideTopBottomVisibility(topLayout: View, bottomLayout: View, show: Boolean) {
val topTransition: Transition = Slide(Gravity.TOP)
topTransition.duration = 600
topTransition.addTarget(topLayout)


val bottomTransition: Transition = Slide(Gravity.BOTTOM)
bottomTransition.duration = 600
bottomTransition.addTarget(bottomLayout)


val transitionSet = TransitionSet()
transitionSet.addTransition(topTransition)
transitionSet.addTransition(bottomTransition)


TransitionManager.beginDelayedTransition(topLayout.parent as ViewGroup, transitionSet)
topLayout.visibility = if (show) View.VISIBLE else View.GONE
bottomLayout.visibility = if (show) View.VISIBLE else View.GONE
}