我有一个线性布局,我想显示或隐藏与动画,推动布局向上或向下每当我改变其可见性。

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

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


当前回答

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
}

}

其他回答

这里有另一种方法来处理多个按钮(在这个例子中是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>

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

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

}

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

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 3.0 (Honeycomb)引入的新动画API,创建这样的动画非常简单。

将视图向下滑动一段距离:

view.animate().translationY(distance);

你可以稍后将视图滑回原来的位置,如下所示:

view.animate().translationY(0);

您还可以轻松地组合多个动画。下面的动画会将一个视图按高度向下滑动,同时淡入:

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

然后,您可以将视图淡出,并将其滑回原始位置。我们还设置了一个AnimatorListener,这样我们可以在动画完成后将视图的可见性设置为GONE:

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

最简单的解决方案:在持有视图的容器上设置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开发者上找到更多细节