it-swarm.com.de

Anzeigen und Ausblenden einer Ansicht mit einer Folie nach oben/unten

Ich habe eine LinearLayout, die ich mit einer Animation anzeigen oder ausblenden möchte, die das Layout bei jeder Änderung der Sichtbarkeit nach oben oder unten schiebt.

Ich habe ein paar Beispiele da draußen gesehen, aber keine davon entspricht meinen Bedürfnissen.

Ich habe zwei XML-Dateien für die Animationen erstellt, weiß jedoch nicht, wie ich sie starten soll, wenn ich die Sichtbarkeit einer LinearLayout ändere. 

249
MichelReap

Mit der neuen Animations-API, die in Android 3.0 (Honeycomb) eingeführt wurde, ist es sehr einfach, solche Animationen zu erstellen.

View um eine Strecke nach unten schieben:

view.animate().translationY(distance);

Sie können das View später wie folgt in die ursprüngliche Position zurückschieben:

view.animate().translationY(0);

Sie können auch mehrere Animationen einfach kombinieren. Die folgende Animation bewegt ein View um seine Höhe nach unten und blendet es gleichzeitig ein:

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

Sie können dann View wieder ausblenden und in die ursprüngliche Position zurückschieben. Wir haben auch eine AnimatorListener gesetzt, damit wir die Sichtbarkeit der View wieder auf GONE setzen können, sobald die Animation abgeschlossen ist:

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

Ich hatte Probleme, die Anwendung der akzeptierten Antwort zu verstehen. Ich brauchte etwas mehr Kontext. Nun, da ich es herausgefunden habe, hier ein vollständiges Beispiel:

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>

Anmerkungen

  • Dank diesem Artikel , der mich in die richtige Richtung weist. Es war hilfreicher als die anderen Antworten auf dieser Seite.
  • Wenn Sie mit der Ansicht auf dem Bildschirm beginnen möchten, initialisieren Sie sie nicht als INVISIBLE.
  • Da wir es komplett außerhalb des Bildschirms animieren, müssen Sie es nicht auf INVISIBLE zurücksetzen. Wenn Sie jedoch nicht vollständig außerhalb des Bildschirms animieren, können Sie eine Alpha-Animation hinzufügen und die Sichtbarkeit mit einer AnimatorListenerAdapter einstellen.
  • Eigenschaftsanimationsdokumente
75
Suragch

Einfachste Lösung: Setzen Sie Android:animateLayoutChanges="true" in den Container, in dem sich Ihre Ansichten befinden.

Um es in einen Kontext zu bringen: Wenn Sie ein Layout wie unten haben, werden alle Sichtbarkeitsänderungen der Ansichten in diesem Container automatisch animiert.

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

    <Views_which_change_visibility>

</LinearLayout>

Weitere Informationen hierzu finden Sie unter Animieren von Layoutänderungen - Android Developer

14
Stefan Medack

Sie können die korrekte Animation starten, wenn sich die Sichtbarkeit der LinearLayout ändert, indem Sie eine neue Unterklasse von LinearLayout erstellen und setVisibility() überschreiben, um die Animations zu starten. Betrachten Sie so etwas:

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);
    }
}
11
user1602259
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);
                }
            });
}
10
Ameen Maheen

Kotlin

Basierend auf Suragch 's answer , ist dies ein eleganter Weg mit der Erweiterung 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)
}

Und wo immer Sie es verwenden möchten, brauchen Sie nur myView.slideUp() oder myView.slideDown()

6

sie können jede Ansicht oder jedes Layout mit dem untenstehenden Code in der Android-App nach oben und unten verschieben

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

Verwenden Sie diese Klasse:

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

Hier ist meine Lösung. Holen Sie sich einfach einen Verweis auf Ihre Ansicht und rufen Sie diese Methode auf:

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

Keine Notwendigkeit, etwas anderes zu tun =)

1
Tiago

Ich hatte einen Eckfall, bei dem die Höhe meiner Ansicht noch zero war ...

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

}
0
Samuel

Sie können die einfachen drei Codezeilen verwenden, um die Animation anzuzeigen ...

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

            }

Animationen zur Änderung der Sichtbarkeit sollten jetzt über Transition API erfolgen, der im Support-Paket (androidx) verfügbar ist. Rufen Sie einfach TransitionManager.beginDelayedTransition mit Slide Transition auf und ändern Sie dann die Sichtbarkeit der Ansicht.

 enter image description here 

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

private void toggle() {
    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>

Überprüfen Sie diese Antwort mit anderen Beispielen für Standard- und benutzerdefinierte Übergänge.

0
ashakirov

Suragchs Antwort in Kotlin. Das hat bei mir funktioniert.

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
}

}

0
olle