Un modo semplice per rendere il lavoro di animazione è ANDATO

Ho una custom pannello di ricerca, che è una parte del layout principale. La maggior parte del tempo, il pannello è nascosto. Vorrei aggiungere visualizzazione/scomparsa di animazione per il pannello. Ecco il layout semplificato estratto:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <RelativeLayout
        android:id="@+id/layoutSearch"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" >
        <EditText
            android:id="@+id/editSearch"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <<Other inner views to be animated>>
    </RelativeLayout>
    <<Other views, which should not be affected by the animation>>
</LinearLayout>

Provare 1: ho aggiunto l’animazione di risorse e di collegarli a @id/layoutSearch con questa linea in XML:

android:layoutAnimation="@anim/search_in_layout"

anim/search_in.xml:

<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/overshoot_interpolator"
    android:fromYDelta="-100%p"
    android:toYDelta="0"
    android:duration="@android:integer/config_longAnimTime" />

anim/search_in_layout.xml:

<layoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/search_in" />

L’animazione funziona bene, ma solo per il pannello che appare. Il pannello scompare in un attimo senza animazione quando ho nasconderlo con:

mSearchLayout.setVisibility(View.GONE);

Provare 2: credo che la soluzione di cui sopra non funziona come l’animazione parametri di destinazione corrisponde all’attuale posizione del pannello. OK, ho creato due più animazione e risorse: anim/search_out.xml e anim/search_out_layout.xml. Le uniche differenze sono scambiati “fromYDelta” e “toYDelta” valori e aggiornamento “android:animazione valore. Allora io carico le risorse del codice e per il @id/layoutSearch come questo:

LayoutAnimationController controller =
    AnimationUtils.loadLayoutAnimation(this, R.anim.search_out_layout);
mSearchLayout.setLayoutAnimation(controller);

“Out” animazione attivato su chiamata di setLayoutAnimation(). Dopo l’animazione il pannello di ricerca ritorna nella posizione originale sullo schermo che aveva prima di essere “fuori”, in animazione. Se provo a chiamare mSearchLayout.setVisibility(View.Se n’è ANDATO) solo dopo setLayoutAnimation(), vedo nessuna animazione, il pannello scompare in una sola volta.

Provare 3: credo che ho bisogno di creare l’animazione nel codice e quindi impostare un ascoltatore su di esso. Quindi dovrei chiamare mSearchLayout.setVisibility(View.Se n’è ANDATO) in onAnimationEnd() gestore per nascondere il pannello dopo l’animazione giocato. Non ho provato ancora. Penso che sia più complicato.

Credo che ho perso qualcosa di importante. C’è un modo per implementare ANDATO animazione un po ‘ facile?

OriginaleL’autore borisstr | 2011-04-08

4 Replies
  1. 4

    Provare 3: credo che ho bisogno di creare l’animazione nel codice e quindi impostare un ascoltatore su di esso. Quindi dovrei chiamare mSearchLayout.setVisibility(View.Se n’è ANDATO) in onAnimationEnd() gestore per nascondere il pannello dopo l’animazione giocato. Non ho provato ancora. Penso che sia più complicato.

    Che è quello che si dovrebbe fare e in realtà non è difficile da ottenere.

    Codice di esempio:

    public class YourClass extends Foo implements AnimationListener {
    
        //...
    
        @Override
        public void onAnimationEnd(Animation a) {
            //Do stuff.
        }
    
        @Override
        public void onAnimationRepeat(Animation a) {    
        }
    
        @Override
        public void onAnimationStart(Animation a) {
        }
    
    }
    A quanto pare, c’è modo più facile fare “fuori” il lavoro di animazione. Grazie.
    Mi chiedo se hai trovato un modo per fare questo senza il fastidioso flash alla fine dell’animazione, quando la vista si pone ancora una volta perché la vista è ANDATO.
    L’aggiunta di un costruttore per questo di prendere una Vista come un argomento è un bel modo per non ripetere il codice di un milione di volte. Allora si può applicare a tutto ciò che si desidera con un.setAnimationListener(nuovo MyAnimationListener(v)); , purché ogni animazione è solo legata a una singola vista.

    OriginaleL’autore Wroclai

  2. 7

    Seguire le risposte di cui sopra : ecco come ho risolto questo problema.

    Si prega di notare che l’impostazione di setFillBefore e setFillAfter nell’animazione prevede di raggiungere i seguenti bug! Problema 5272: Vista la visibilità di Vista.ANDATO ancora genera eventi di tocco
    http://code.google.com/p/android/issues/detail?id=5272

    File : MyWebViewActivity.java

    private View mBottomOverlay;
    private View mTopOverlay;
    private boolean mControlsOverlayVisible;
    private Animation mSlideBottomUpAnimation;
    private Animation mSlideBottomDownAnimation;
    private Animation mSlideTopDownAnimation;
    private Animation mSlideTopUpAnimation;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.reader_layout);
    
        //load the overlay resources
        mTopOverlay = findViewById(R.id.reader_overlay_top_toolbar);
        mBottomOverlay = findViewById(R.id.reader_overlay_bottom_toolbar);
    
        initAnimations();
    }
    
    private void initAnimations() {
    
        final AnimationListener makeTopGone = new AnimationListener() {
    
            @Override
            public void onAnimationStart(Animation animation) {}
    
            @Override
            public void onAnimationRepeat(Animation animation) {}
    
            @Override
            public void onAnimationEnd(Animation animation) {
                Log.d(TAG, "onAnimationEnd - makeTopGone");
                mTopOverlay.setVisibility(View.GONE);
            }
        };
    
        final AnimationListener makeBottomGone = new AnimationListener() {
    
            @Override
            public void onAnimationStart(Animation animation) {}
    
            @Override
            public void onAnimationRepeat(Animation animation) {
            }
    
            @Override
            public void onAnimationEnd(Animation animation) {
                Log.d(TAG, "onAnimationEnd - makeBottomGone");
                mBottomOverlay.setVisibility(View.GONE);
            }
        };
    
        final AnimationListener makeTopVisible = new AnimationListener() {
    
            @Override
            public void onAnimationStart(Animation animation) {
                Log.d(TAG, "onAnimationStart - makeTopVisible");
                mTopOverlay.setVisibility(View.VISIBLE);
            }
    
            @Override
            public void onAnimationRepeat(Animation animation) {}
    
            @Override
            public void onAnimationEnd(Animation animation) {}
        };
    
        final AnimationListener makeBottomVisible = new AnimationListener() {
    
            @Override
            public void onAnimationStart(Animation animation) {
                Log.d(TAG, "onAnimationStart - makeBottomVisible");
                mBottomOverlay.setVisibility(View.VISIBLE);
            }
    
            @Override
            public void onAnimationRepeat(Animation animation) {}
    
            @Override
            public void onAnimationEnd(Animation animation) {}
        };
    
        mSlideTopUpAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_top_up);
        mSlideBottomDownAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_down);
        mSlideTopUpAnimation.setAnimationListener(makeTopGone);
        mSlideBottomDownAnimation.setAnimationListener(makeBottomGone);
    
        mSlideTopDownAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_top_down);
        mSlideBottomUpAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_up);
        mSlideTopDownAnimation.setAnimationListener(makeTopVisible);
        mSlideBottomUpAnimation.setAnimationListener(makeBottomVisible);
    }
    
    private void hideControlOverlays() {
        Log.d(TAG, "hideControlOverlays");
        mTopOverlay.startAnimation(mSlideTopUpAnimation);
        mBottomOverlay.startAnimation(mSlideBottomDownAnimation);
        mControlsOverlayVisible = false;
    }
    
    private void showControlOverlays() {
        Log.d(TAG, "showControlOverlays");
        mTopOverlay.startAnimation(mSlideTopDownAnimation);
        mBottomOverlay.startAnimation(mSlideBottomUpAnimation);
        mControlsOverlayVisible = true;
    }

    File : /res/layout/reader_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/reader_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <WebView
            android:id="@+id/webview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
        <FrameLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/reader_overlay_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <LinearLayout
                android:id="@+id/reader_overlay_top_toolbar"
                android:layout_width="fill_parent"
                android:layout_height="140dp"
                android:background="#80000000" >
    
                <include layout="@layout/toolbar_top" />
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/reader_overlay_bottom_toolbar"
                android:layout_width="fill_parent"
                android:layout_height="140dp"
                android:layout_gravity="bottom"
                android:background="#80000000"
                android:orientation="horizontal" >
    
                <include layout="@layout/toolbar_bottom_left" />
            </LinearLayout>
        </FrameLayout>
    </FrameLayout>

    File : /res/anim/slide_bottom_down.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillEnabled="true"
        android:interpolator="@android:anim/accelerate_interpolator" >
        <translate
            android:duration="@android:integer/config_shortAnimTime"
            android:fromYDelta="0"
            android:toYDelta="100%" />
    </set>

    File : /res/anim/slide_bottom_up.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_interpolator" >
        <translate
            android:duration="@android:integer/config_shortAnimTime"
            android:fromYDelta="100%"
            android:toYDelta="0" />
    </set>

    File : /res/anim/slide_top_down.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_interpolator" >
        <translate
            android:duration="@android:integer/config_shortAnimTime"
            android:fromYDelta="-100%"
            android:toYDelta="0" />
    </set>

    File : /res/anim/slide_top_up.xml

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:fillEnabled="true"
        android:interpolator="@android:anim/accelerate_interpolator" >
        <translate
            android:duration="@android:integer/config_shortAnimTime"
            android:fromYDelta="0"
            android:toYDelta="-100%" />
    </set>
    Mi puoi dire quando ti chiamano quando/dove si chiamano le funzioni hideControlOverlays() e showControlOverlays() ? Sto cercando di sviluppare qualcosa di simile. La vostra risposta sarà davvero utile. Grazie
    è possibile chiamare il showControlsOverlay() il metodo utilizzato per esempio da un onTouch o onClick ascoltatore in una vista. Il hideControlsOverlay() metodo può essere chiamato da un altro onTouch o gestore onClick, o è possibile impostare un ritardo eseguibile chiamare dopo pochi secondi per respingere automaticamente la sovrapposizione senza l’interazione dell’utente.
    Grazie, ho capito di lavoro. Molto bella soluzione. +1
    Grazie, clearAnimation() risolto il problema per me.

    OriginaleL’autore Akos Cz

  3. 4

    è necessario chiamare setFillAfter() di Animazione Classe per contenere l’animazione dopo la riproduzione.

    RelativeLayout layout = (RelativeLayout) findViewById(R.id.layoutSearch);
    Animation a = AnimationUtils.loadAnimation(this, R.anim.push_down);
    a=setFillAfter(true); 
    layout.setLayoutAnimation(new LayoutAnimationController(a));
    layout.startLayoutAnimation();

    OriginaleL’autore Catherine Lau

  4. 2

    Impostazione di una Vista GONE rimuove efficacemente dal formato. Invece dovrebbe essere impostato a INVISIBLE, e quindi GONE una volta completata l’animazione, se necessario.

    Grazie per la tua risposta. Ho cercato di essere INVISIBILE. Sembra, non c’è nessun motivo per farlo. Uno ancora bisogno di impostare il layout di animazione e l’ascoltatore nel codice. Animazione inizia setLayoutAnimation(), non c’è bisogno di impostare INVISIBILE. Questo è molto strano per me, come “in” animazione non richiedono una singola riga di codice…
    in questo modo il lavoro di Vista visualizzare o nascondere, non credo che ViewGroup funzionare bene, ma grazie Giuseppe-Conte fornire.

    OriginaleL’autore Joseph Earl

Lascia un commento