Android fügt einfache Animationen hinzu, während die Sichtbarkeit (view.Gone)

237

Ich habe ein einfaches Layout entworfen. Ich habe das Design ohne Animation fertiggestellt, aber jetzt möchte ich Animationen hinzufügen, wenn die Textansicht auf ein Ereignis klickt, und ich weiß nicht, wie ich es verwenden soll. Hat mein XML-Design gut ausgesehen oder nicht? Anregungen wäre dankbar.

Mein XML

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16" >

<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#00DDA0"
    android:layout_weight="3" >
</LinearLayout>
 <TextView
        android:id="@+id/Information1"
        android:layout_width="match_parent"
        android:layout_height="1dp" 
        android:text="Child Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>

 <LinearLayout
     android:id="@+id/layout1"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="8.5"
     android:background="#BBBBBB"
     android:orientation="vertical" >

     <TextView
         android:id="@+id/textView1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
 </LinearLayout>

  <TextView
        android:id="@+id/Information2"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Parent Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
  <LinearLayout 
          android:id="@+id/layout2"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView2"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
   <TextView
        android:id="@+id/Information3"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Siblings" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
   <LinearLayout 
          android:id="@+id/layout3"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView3"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
    <TextView
        android:id="@+id/Information4"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Teacher Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
    <LinearLayout 
          android:id="@+id/layout4"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView4"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
     <TextView
        android:id="@+id/Information5"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Grade Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
     <LinearLayout 
          android:id="@+id/layout5"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
      <TextView
        android:id="@+id/Information6"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Health Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
      <LinearLayout 
          android:id="@+id/layout6"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
    <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" 
         android:layout_weight="8.5" />
      </LinearLayout>

</LinearLayout>

Mein Java

public class Certify_Info extends Activity {

    private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
    private static LinearLayout l1,l2,l3,l4,l5,l6;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_certify__info);

        tv1=(TextView) findViewById(R.id.Information1);
        tv2=(TextView) findViewById(R.id.Information2);
        tv3=(TextView) findViewById(R.id.Information3);
        tv4=(TextView) findViewById(R.id.Information4);
        tv5=(TextView) findViewById(R.id.Information5);
        tv6=(TextView) findViewById(R.id.Information6); 

        l1=(LinearLayout) findViewById(R.id.layout1);
        l2=(LinearLayout) findViewById(R.id.layout2);
        l3=(LinearLayout) findViewById(R.id.layout3);
        l4=(LinearLayout) findViewById(R.id.layout4);
        l5=(LinearLayout) findViewById(R.id.layout5);
        l6=(LinearLayout) findViewById(R.id.layout6); 

        l2.setVisibility(View.GONE);
        l3.setVisibility(View.GONE); 
        l4.setVisibility(View.GONE); 
        l5.setVisibility(View.GONE);
        l6.setVisibility(View.GONE);

        tv1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l1.setVisibility(View.VISIBLE);
            }
        });
        tv2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l2.setVisibility(View.VISIBLE);
            }
        });
        tv3.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l3.setVisibility(View.VISIBLE);

            }
        });
        tv4.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l4.setVisibility(View.VISIBLE); 
            }
        });
        tv5.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l6.setVisibility(View.GONE);
                l5.setVisibility(View.VISIBLE); 
            }
        });
        tv6.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.VISIBLE);
            }
        });

    }
}
arun
quelle

Antworten:

702

Sie können zwei Dinge tun, um Animationen hinzuzufügen: Erstens können Sie Android Layoutänderungen für Sie animieren lassen. Auf diese Weise werden jedes Mal, wenn Sie etwas im Layout ändern, z. B. die Sichtbarkeit der Ansicht oder die Ansichtspositionen ändern, automatisch Überblendungs- / Übergangsanimationen erstellt. Um dieses Set zu verwenden

android:animateLayoutChanges="true"

auf dem Wurzelknoten in Ihrem Layout.

Ihre zweite Option wäre das manuelle Hinzufügen von Animationen. Ich schlage vor, dass Sie die neue Animations-API verwenden, die in Android 3.0 (Honeycomb) eingeführt wurde. Ich kann Ihnen einige Beispiele geben:

Dies blendet ein View:

view.animate().alpha(0.0f);

Dies blendet es wieder ein:

view.animate().alpha(1.0f);

Dies bewegt einen nach Viewunten um seine Höhe:

view.animate().translationY(view.getHeight());

Dies bringt den Viewin seine Ausgangsposition zurück, nachdem er an einen anderen Ort verschoben wurde:

view.animate().translationY(0);

Sie können auch setDuration()die Dauer der Animation festlegen. Dies wird beispielsweise Viewüber einen Zeitraum von 2 Sekunden ausgeblendet :

view.animate().alpha(0.0f).setDuration(2000);

Und Sie können so viele Animationen kombinieren, wie Sie möchten. Dies blendet beispielsweise a aus Viewund verschiebt es gleichzeitig über einen Zeitraum von 0,3 Sekunden nach unten:

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300);

Sie können der Animation auch einen Listener zuweisen und auf alle Arten von Ereignissen reagieren. Zum Beispiel, wenn die Animation beginnt, wenn sie endet oder sich wiederholt usw. Wenn Sie die abstrakte Klasse verwenden, müssen AnimatorListenerAdapterSie nicht alle Rückrufe gleichzeitig implementieren, AnimatorListenersondern nur die, die Sie benötigen. Dies macht den Code besser lesbar. Der folgende Code blendet beispielsweise aus und Viewverschiebt ihn über einen Zeitraum von 0,3 Sekunden (300 Millisekunden) um seine Höhe nach unten. Wenn die Animation fertig ist, wird seine Sichtbarkeit auf eingestellt View.GONE.

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300)
        .setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                view.setVisibility(View.GONE);
            }
        });
Xaver Kapeller
quelle
6
@ Natix Ich würde diesen Superanruf nicht als redundant bezeichnen. Nehmen Sie keine oberflächlichen Änderungen vor, da ist nichts falsch.
Xaver Kapeller
5
Ist gut, aber das Gegenteil funktioniert nicht richtig, warum? view.setVisibility (View.VISIBLE); MIT Alpha (1.0f), erscheinen mit 100 Polster oben ...
liefern
15
Die Animation muss gelöscht werden, bevor die Sichtbarkeit eingestellt wird >> view.clearAnimation(); view.setVisibility(View.GONE);Andernfalls bleibt das Layout unsichtbar und nicht verschwunden.
Eftekhari
2
@Eftekhari Sie sind überhaupt nicht ressourcenintensiv. Und wenn Sie eine aktuelle Android-Version haben, aber dennoch Verzögerungen feststellen, haben Sie wahrscheinlich ein älteres Telefon mit wenig Speicher oder einem schlechten Grafikchip. Und ich spreche nicht von einer neuen Bibliothek. Animatoren sind einheimisch. Sie sind Teil des Android Framework. Sie wurden vor 5 Jahren veröffentlicht und heute unterstützen 97,9% aller Geräte sie. Es gibt keinen Grund, Animators nicht zu verwenden oder zumindest einen ViewCompat.animate()Teil der Support-Bibliothek, der Animators in neueren Versionen und View Animations unter Android 3.0 und niedriger verwendet.
Xaver Kapeller
1
Aber wenn 97,9% aller Geräte Android 4.0 und höher sind, bleibt nicht viel von einem Anwendungsfall übrig ViewCompat.animate().
Xaver Kapeller
67

Der einfachste Weg, VisibilityÄnderungen zu animieren , ist die Verwendung des Transition APISupport-Pakets (androidx). Rufen Sie einfach die TransitionManager.beginDelayedTransitionMethode auf und ändern Sie die Sichtbarkeit der Ansicht. Es gibt verschiedene Standardübergänge wie Fade, Slide.

import androidx.transition.TransitionManager;
import androidx.transition.Transition;
import androidx.transition.Fade;

private void toggle() {
    Transition transition = new Fade();
    transition.setDuration(600);
    transition.addTarget(R.id.image);

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

Wo parentist das übergeordnete Element ViewGroupder animierten Ansicht? Ergebnis:

Geben Sie hier die Bildbeschreibung ein

Hier ist das Ergebnis mit SlideÜbergang:

import androidx.transition.Slide;

Transition transition = new Slide(Gravity.BOTTOM);

Geben Sie hier die Bildbeschreibung ein

Es ist einfach, einen benutzerdefinierten Übergang zu schreiben, wenn Sie etwas anderes benötigen. Hier ist ein Beispiel, mit CircularRevealTransitiondem ich in einer anderen Antwort geschrieben habe . Die Ansicht wird mit der CircularReveal-Animation ein- und ausgeblendet.

Transition transition = new CircularRevealTransition();

Geben Sie hier die Bildbeschreibung ein

android:animateLayoutChanges="true"Die Option macht dasselbe, sie verwendet nur AutoTransition als Übergang.

Ashakirov
quelle
@TouhidulIslam Nr. Diese Klassen sind im AndroidX-Paket verfügbar. Alles ist abwärtskompatibel
ashakirov
2
Was ist mit dem Erweitern / Reduzieren einer Ansichtsgruppe?
TheRealChx101
Kannst du mehrere beginDelayedTransitions machen?
Jeongbebs
26

Bitte überprüfen Sie dies Link. Dies ermöglicht Animationen wie L2R-, R2L-, T2B- und B2T-Animationen.

Dieser Code zeigt die Animation von links nach rechts

TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);

Wenn Sie es von R2L aus tun möchten, verwenden Sie

TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);

für von oben nach unten als

TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());

und umgekehrt ..

NullPointerException
quelle
8
Dies verschiebt die Ansicht von ihrer ursprünglichen Position.
Relm
24

Versuchen Sie, diese Zeile zum übergeordneten XML-Layout hinzuzufügen

 android:animateLayoutChanges="true"

Ihr Layout wird so aussehen

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16">

    .......other code here

    </LinearLayout>
Ricardo Romo
quelle
das hat bei mir funktioniert. Mein Setup verwendet ein Einschränkungslayout als Stammansicht. Wenn die Ansicht auf View.VISIBLE eingestellt ist, wird die Animation angezeigt
EdgeDev
sehr einfache und elegante Lösung
Naveed Ahmad
11

Basierend auf der Antwort von @Xaver Kapeller habe ich eine Möglichkeit gefunden, eine Bildlaufanimation zu erstellen, wenn neue Ansichten auf dem Bildschirm angezeigt werden (und auch eine Animation, um sie auszublenden).

Es geht von diesem Zustand aus:

  • Taste
  • Letzter Knopf

zu

  • Taste
  • Knopf 1
  • Taste 2
  • Taste 3
  • Taste 4
  • Letzter Knopf

und umgekehrt.

Wenn der Benutzer auf die erste Schaltfläche klickt, werden die Elemente "Schaltfläche 1", "Schaltfläche 2", "Schaltfläche 3" und "Schaltfläche 4" mithilfe einer Überblendanimation angezeigt und das Element "Letzte Schaltfläche" wird bis zum Ende nach unten verschoben. Die Höhe des Layouts ändert sich ebenfalls, sodass die Bildlaufansicht ordnungsgemäß verwendet werden kann.

Dies ist der Code zum Anzeigen von Elementen mit Animation:

private void showElements() {
    // Precondition
    if (areElementsVisible()) {
        Log.w(TAG, "The view is already visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    // the alpha as 0.0. Otherwise the animation won't be shown
    mHiddenLinearLayout.setVisibility(View.VISIBLE);
    mHiddenLinearLayout.setAlpha(0.0f);
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(1.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    updateShowElementsButton();
                    mHiddenLinearLayout.animate().setListener(null);
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(mHiddenLinearLayoutHeight);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
}

und dies ist der Code zum Ausblenden von Elementen der Animation:

private void hideElements() {
    // Precondition
    if (!areElementsVisible()) {
        Log.w(TAG, "The view is already non-visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(0.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    Log.v(TAG, "Animation ended. Set the view as gone");
                    super.onAnimationEnd(animation);
                    mHiddenLinearLayout.setVisibility(View.GONE);
                    // Hack: Remove the listener. So it won't be executed when
                    // any other animation on this view is executed
                    mHiddenLinearLayout.animate().setListener(null);
                    updateShowElementsButton();
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(0);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight();
}

Beachten Sie, dass die Methode zum Ausblenden der Animation einen einfachen Hack enthält. Auf dem Animations-Listener mHiddenLinearLayout musste ich den Listener selbst entfernen, indem ich Folgendes verwendete:

mHiddenLinearLayout.animate().setListener(null);

Dies liegt daran, dass, sobald ein Animationslistener an eine Ansicht angehängt ist, das nächste Mal, wenn eine Animation in dieser Ansicht ausgeführt wird, auch der Listener ausgeführt wird. Dies könnte ein Fehler im Animations-Listener sein.

Der Quellcode des Projekts befindet sich auf GitHub: https://github.com/jiahaoliuliu/ViewsAnimated

Viel Spaß beim Codieren!

Update : Für jeden Listener, der an die Ansichten angehängt ist, sollte er nach Ende der Animation entfernt werden. Dies geschieht mit

view.animate().setListener(null);
jiahao
quelle
Dies ist die beste Antwort
Naveen Kumar M
1
Die view.animate().setListener(null);Aussage hat mir den Tag gerettet. Dies scheint definitiv ein Fehler zu sein.
Michal Vician
@ MichaelVician Ich bin froh, dass es so war!
Jiahao
8

Ich konnte ein Menü folgendermaßen ein- / ausblenden:

MenuView.java (erweitert FrameLayout)

private final int ANIMATION_DURATION = 500;

public void showMenu()
{
    setVisibility(View.VISIBLE);
    animate()
            .alpha(1f)
            .setDuration(ANIMATION_DURATION)
            .setListener(null);
}

private void hideMenu()
{
    animate()
            .alpha(0f)
            .setDuration(ANIMATION_DURATION)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(View.GONE);
                }
            });
}

Quelle

Nelson Almendra
quelle