2012-05-11 2 views
7

Ne ha uno strano. Sono riuscito a ridurlo ad un esempio molto semplice. Davvero non riesco a capirlo.LinearyLayout non verrà ridimensionato una volta che l'altezza è 0

Ho un LinearLayout all'interno di un LinearLayout. Voglio ridimensionare il bambino usando un'animazione (che a volte sto lavorando a meraviglia). Ecco il mio XML di layout.

<?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:orientation="vertical" > 

    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> 
     <!-- Lots more controls will appear above --> 
     <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:id="@+id/animation_subject"> 
      <TextView 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:text="@string/hello" 
       android:gravity="center" /> 
     </LinearLayout> 
     <!-- Lots more controls will appear below --> 
    </LinearLayout> 

    <Button android:text="Slide it Down!" android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="btnDoAnimDown_OnClick" /> 

</LinearLayout> 

Ora, come potete vedere, c'è un pulsante, ed ecco il codice per quel pulsante.

public void btnDoAnimDown_OnClick(View v) 
{ 
    View pnlSlider = findViewById(R.id.animation_subject); 
    pnlSlider.measure(1000, 1000); 
    DropDownAnim anim = new DropDownAnim(pnlSlider, pnlSlider.getMeasuredHeight(), true); 
    anim.setDuration(2000); 
    pnlSlider.startAnimation(anim); 

    return;  
} 

Se si dovesse eseguire ora, non scorrere verso il basso. Affatto. Tuttavia, se dovessi spostare il pulsante nel LinearLayout che ho chiamato Panoramica e metterlo dopo il Child LinearLayout, funzionerà benissimo! In questo modo ...

<?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:orientation="vertical" > 

    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> 
     <!-- Lots more controls will appear above --> 
     <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:id="@+id/animation_subject"> 
      <TextView 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:text="@string/hello" 
       android:gravity="center" /> 
     </LinearLayout> 
     <!-- Lots more controls will appear below --> 
     <Button android:text="Slide it Down!" android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="btnDoAnimDown_OnClick" /> 
    </LinearLayout> 

</LinearLayout> 

Ora scorre verso il basso, esattamente come previsto. Chiaramente qualcosa sta andando con il layout genitore ... Come getMeasuredHeight() restituisce il valore corretto, è solo l'animazione non viene effettivamente eseguita!

Questa è la lezione di animazione, mi manca qualcosa di stupido? Probabilmente sono!

import android.util.Log; 
import android.view.View; 
import android.view.animation.Animation; 
import android.view.animation.Transformation; 

public class DropDownAnim extends Animation { 
    int targetHeight; 
    View view; 
    boolean down; 

    public DropDownAnim(View view, int targetHeight, boolean down) { 
     this.view = view; 
     this.targetHeight = targetHeight; 
     this.down = down; 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     int newHeight; 
     if (down) { 
      newHeight = (int) (targetHeight * interpolatedTime); 
     } else { 
      newHeight = (int) (targetHeight * (1 - interpolatedTime)); 
     } 
     Log.d("new height", String.valueOf(newHeight)); 
     view.getLayoutParams().height = newHeight; 
     view.requestLayout(); 
    } 

    @Override 
    public void initialize(int width, int height, int parentWidth, 
      int parentHeight) { 
     super.initialize(width, height, ((View)view.getParent()).getWidth(), parentHeight); 
    } 

    @Override 
    public boolean willChangeBounds() { 
     return true; 
    } 
} 

Qualsiasi aiuto sarebbe fantastico!

+0

esattamente una soluzione, ma lasciare che il pulsante essere lì e impostare la sua visibilità a gone. Funziona in questo modo? – Urban

+0

Quindi non potrò cliccarlo, per testarlo. Metterò un altro oggetto lì dentro e ci provo. –

+0

No, nessun dado.Se il fratello successivo non è il pulsante che causa l'animazione, non lo esegue. Che strano. Molto confuso qui. –

risposta

2

non lo faccio sapere perché il tuo codice non vuole fare l'animazione. Ma ho risolto con un piccolo cambiamento. Quello che ho fatto è applicare l'animazione al layout genitore e non al layout che stai trasformando. ecco il codice del xml, ho solo aggiunto un Id al layout genitore:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <LinearLayout android:id="@+id/animation_subject_parent" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> 
     <!-- Lots more controls will appear above --> 
     <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:id="@+id/animation_subject"> 
      <TextView 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:text="@string/hello" 
       android:gravity="center" /> 
     </LinearLayout> 
     <!-- Lots more controls will appear below --> 
    </LinearLayout> 
     <Button android:text="Slide it Down!" android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="btnDoAnimDown_OnClick" /> 

</LinearLayout> 

E qui è il codice del pulsante clic:

public void btnDoAnimDown_OnClick(View v) 
{ 
    View pnlSlider = findViewById(R.id.animation_subject); 
    View parent = findViewById(R.id.animation_subject_parent); 

    pnlSlider.measure(1000, 1000); 
    DropDownAnim anim = new DropDownAnim(pnlSlider, pnlSlider.getMeasuredHeight(), true); 
    anim.setDuration(2000); 

    parent.startAnimation(anim); 

    return;  
} 
Non
3

Lasciami indovinare qui.

Nel primo layout, il layout interno e il pulsante condividono l'allineamento lineare esterno.

<?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:orientation="vertical" > 

    <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical"> 
     <!-- Lots more controls will appear above --> 
     <LinearLayout android:layout_width="fill_parent" android:layout_height="0dp" android:id="@+id/animation_subject"> 
      <TextView 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:text="@string/hello" 
       android:gravity="center" /> 
     </LinearLayout> 
     <!-- Lots more controls will appear below --> 
    </LinearLayout> 

    <Button android:text="Slide it Down!" android:layout_width="fill_parent" android:layout_height="wrap_content" android:onClick="btnDoAnimDown_OnClick" /> 

</LinearLayout> 

Che rende il layout esterno un ViewGroup!

Ma nel metodo di inizializzazione della tua animazione fai un cast sul genitore della vista data.

Si lancia su Visualizza, che non è nel 1 ° layout.

Nel tuo secondo è, ed è per questo che funziona.

quindi vorrei a dargli un casting tentativo di ViewGroup invece:

@Override 
    public void initialize(int width, int height, int parentWidth, 
      int parentHeight) { 
     super.initialize(width, height, ((ViewGroup)view.getParent()).getWidth(), parentHeight); 
    } 
+0

Bel tentativo, ma niente da fare. ripristinato il intialize a quello che dovrebbe essere, quindi passa in parentWidth e parentHeight, invece di calcolare, ancora nessun dado. :( –

2

Non sono sicuro se vi aiuterà, ma tenta di aggiungere android:layout_weight="1" a LinearLayout con id="@+id/animation_subject"

+0

Ora il layout si esaurisce nello spazio, quindi genera la sua altezza. Quando si fa clic su slideDown funziona comunque, salta a 0, quindi scorre verso il basso, ma il problema essendo la sua altezza non è 0 inizialmente. –

+0

il problema è che la dimensione 0 è impostata nel xml indica che la dimensione dovrebbe essere impostato automaticamente in base alle dimensioni di visualizzazione dei bambini. Come hack puoi impostare la visibilità della vista su 'gone' in xml e al primo avvio della dimensione del set di animazione su 0 a livello di programmazione e impostare la visibilità su' View.VISIBLE' – Dmitry