Android che aggiunge animazioni semplici durante la visibilità (view.Gone)


237

Ho progettato un layout semplice, ho terminato il progetto senza animazione, ma ora voglio aggiungere animazioni quando si fa clic sull'evento di testo e non so come usarlo. Il mio design XML ha un bell'aspetto o no? Tutti i suggerimenti sarebbero apprezzati.

Il mio 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>

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

    }
}

Risposte:


706

Puoi fare due cose per aggiungere animazioni, prima puoi permettere ad Android di modificare le modifiche del layout per te. In questo modo ogni volta che cambi qualcosa nel layout come cambiare la visibilità della vista o visualizzare le posizioni Android creerà automaticamente animazioni di dissolvenza / transizione. Per usare quel set

android:animateLayoutChanges="true"

sul nodo principale nel layout.

La tua seconda opzione sarebbe quella di aggiungere manualmente animazioni. Per questo ti suggerisco di utilizzare la nuova API di animazione introdotta in Android 3.0 (Honeycomb). Posso darti alcuni esempi:

Questo svanisce a View:

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

Questo si dissolve di nuovo in:

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

Questo si sposta Viewverso il basso della sua altezza:

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

Ciò riporta la Viewposizione iniziale dopo che è stata spostata da qualche altra parte:

view.animate().translationY(0);

Puoi anche usare setDuration()per impostare la durata dell'animazione. Ad esempio, questo si attenua Viewper un periodo di oltre 2 secondi:

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

E puoi combinare tutte le animazioni che desideri, ad esempio questa si attenua Viewe la sposta contemporaneamente verso il basso per un periodo di 0,3 secondi:

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

E puoi anche assegnare un ascoltatore all'animazione e reagire a tutti i tipi di eventi. Come quando inizia l'animazione, quando termina o si ripete, ecc. Usando la classe astratta AnimatorListenerAdapternon è necessario implementare tutti i callback di AnimatorListeneruna volta ma solo quelli di cui hai bisogno. Questo rende il codice più leggibile. Ad esempio, il codice seguente si attenua e lo Viewsposta verso il basso della sua altezza per un periodo di 0,3 secondi (300 millisecondi) e al termine dell'animazione la sua visibilità è impostata su 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);
            }
        });

6
@Natix Non chiamerei quella super chiamata ridondante. Non apportare modifiche superficiali non c'è nulla di sbagliato.
Xaver Kapeller,

5
È buono ma l'inverso non funziona correttamente perché? view.setVisibility (View.VISIBLE); CON alpha (1.0f), appare con 100 imbottitura superiore ...
consegna l'

15
È necessario cancellare l'animazione prima di impostare la visibilità >> view.clearAnimation(); view.setVisibility(View.GONE);altrimenti il ​​layout rimarrà invisibile e non scomparirà.
Eftekhari,

2
@Eftekhari Non richiedono affatto risorse. E se hai una versione Android aggiornata, ma hai ancora un ritardo rispetto a quello che probabilmente hai un telefono più vecchio con poca memoria o un chip grafico difettoso. E non sto parlando di una nuova biblioteca. Gli animatori sono nativi. Fanno parte di Android Framework. Sono stati rilasciati 5 anni fa e oggi il 97,9% di tutti i dispositivi li supporta. Non vi è alcun motivo per non utilizzare gli animatori o quanto meno ViewCompat.animate()fa parte della libreria di supporto e utilizza gli animatori nelle versioni più recenti e Visualizza animazioni su Android 3.0 e versioni successive.
Xaver Kapeller,

1
Ma quando il 97,9% di tutti i dispositivi è Android 4.0 e versioni successive, non è rimasto molto del caso d'uso ViewCompat.animate().
Xaver Kapeller,

70

Il modo più semplice per animare le Visibilitymodifiche è usare quello Transition APIdisponibile nel pacchetto support (androidx). Basta chiamare il TransitionManager.beginDelayedTransitionmetodo quindi cambiare la visibilità della vista. Ci sono diverse transizioni predefinite come 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);
}

Dov'è il parentgenitore ViewGroupdella vista animata. Risultato:

inserisci qui la descrizione dell'immagine

Ecco il risultato con la Slidetransizione:

import androidx.transition.Slide;

Transition transition = new Slide(Gravity.BOTTOM);

inserisci qui la descrizione dell'immagine

È facile scrivere una transizione personalizzata se hai bisogno di qualcosa di diverso. Ecco un esempio con CircularRevealTransitioncui ho scritto in un'altra risposta . Mostra e nasconde la vista con l'animazione CircularReveal.

Transition transition = new CircularRevealTransition();

inserisci qui la descrizione dell'immagine

android:animateLayoutChanges="true"L'opzione fa la stessa cosa, usa solo AutoTransition come transizione.


@TouhidulIslam no. Queste classi sono disponibili nel pacchetto androidx. Tutto è retrocompatibile
ashakirov il

2
Che ne dici di espandere / comprimere un gruppo di visualizzazioni?
TheRealChx101,

Puoi fare più beginDelayedTransitions?
Jeongbebs l'

26

Si prega di controllare questo link. Ciò consentirà animazioni come animazioni L2R, R2L, T2B, B2T.

Questo codice mostra l'animazione da sinistra a destra

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

se si desidera farlo da R2L, utilizzare

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

per dall'alto verso il basso come

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

e viceversa ..


8
Questo sposta la vista dalla sua posizione originale.
Relm

24

Prova ad aggiungere questa riga al layout padre XML

 android:animateLayoutChanges="true"

Il layout sarà simile a questo

<?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>

questo ha funzionato per me. La mia configurazione utilizza un layout di vincolo come vista principale. Quando la vista è impostata su View.VISIBLE, viene visualizzata l'animazione
EdgeDev

soluzione molto semplice ed elegante
Naveed Ahmad,

11

Basandomi sulla risposta di @Xaver Kapeller, ho scoperto un modo per creare un'animazione di scorrimento quando sullo schermo appaiono nuove viste (e anche un'animazione per nasconderle).

Va da questo stato:

  • Pulsante
  • Ultimo pulsante

per

  • Pulsante
  • Pulsante 1
  • Pulsante 2
  • Pulsante 3
  • Pulsante 4
  • Ultimo pulsante

e viceversa.

Pertanto, quando l'utente fa clic sul primo pulsante, gli elementi "Pulsante 1", "Pulsante 2", "Pulsante 3" e "Pulsante 4" verranno visualizzati utilizzando l'animazione di dissolvenza e l'elemento "Ultimo pulsante" si sposterà verso il basso fino alla fine. Anche l'altezza del layout cambierà, consentendo di utilizzare correttamente la vista di scorrimento.

Questo è il codice per mostrare gli elementi con l'animazione:

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

e questo è il codice per nascondere elementi dell'animazione:

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

Si noti che esiste un semplice trucco sul metodo per nascondere l'animazione. Sul listener di animazione mHiddenLinearLayout, ho dovuto rimuovere il listener stesso usando:

mHiddenLinearLayout.animate().setListener(null);

Questo perché una volta che un listener di animazione è collegato a una vista, la volta successiva in cui viene eseguita qualsiasi animazione in questa vista, verrà eseguito anche il listener. Potrebbe trattarsi di un bug nel listener dell'animazione.

Il codice sorgente del progetto è su GitHub: https://github.com/jiahaoliuliu/ViewsAnimated

Buona programmazione!

Aggiornamento : per qualsiasi ascoltatore collegato alle viste, dovrebbe essere rimosso al termine dell'animazione. Questo viene fatto usando

view.animate().setListener(null);

Questa è la risposta migliore
Naveen Kumar M

1
La view.animate().setListener(null);dichiarazione mi ha salvato la giornata. Questo sembra sicuramente essere un bug.
Michal Vician,

@MichalVician Lieto!
jiahao,

8

Sono stato in grado di mostrare / nascondere un menu in questo modo:

MenuView.java (estende 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);
                }
            });
}

fonte

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.