2012-08-17 17 views
13

Tengo un ListView con elementos en él. Cuando el usuario hace clic en un elemento, su altura debe escalar a cero y todos los elementos a continuación deben desplazarse hacia arriba. Mi código a continuación no funciona. Con mi código, el elemento al que se hizo clic se escala a la derecha, pero los elementos a continuación no se desplazan hacia arriba, permanecen en la misma posición. También lo probé con LinearLayout, pero existe el mismo problema.ListView elemento animado único

Hay una aplicación que hace esto bien. Se llama Tasks.

This little image should explain the problem

Mi implementación actual se parece a esto:

@Override 
public void onItemClick(AdapterView<?> arg0, View v, final int index, 
     long id) { 
    Animation anim = AnimationUtils.loadAnimation(getActivity(), 
      R.anim.scaleup); 
    v.startAnimation(anim); 
} 

<set android:shareInterpolator="false" > 
    <scale 
     android:duration="700" 
     android:fillAfter="false" 
     android:fillBefore="false" 
     android:fromXScale="1.0" 
     android:fromYScale="1.0" 
     android:interpolator="@android:anim/accelerate_decelerate_interpolator" 
     android:pivotY="0%" 
     android:toXScale="1.0" 
     android:toYScale="0.0" /> 
</set> 

+1

¿Cómo es su implementación actual? – wsanville

+0

@wsanville fuente añadida –

+0

Es realmente difícil de entender lo que está pidiendo –

Respuesta

7

Aquí es una clase que hice (modificada desde source I found here) que puede darle la funcionalidad que desea.

public class FadeUpAnimation extends Animation { 

int mFromHeight; 
View mView; 

public FadeUpAnimation(View view) { 
    this.mView = view; 
    this.mFromHeight = view.getHeight(); 
} 

@Override 
protected void applyTransformation(float interpolatedTime, Transformation t) { 
    int newHeight; 
    newHeight = (int) (mFromHeight * (1 - interpolatedTime)); 
    mView.getLayoutParams().height = newHeight; 
    mView.setAlpha(1 - interpolatedTime); 
    mView.requestLayout(); 
} 

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

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

Entonces así es como lo estoy usando

View tv = ... 
Animation a = new FadeUpAnimation(tv); 
a.setInterpolator(new AccelerateInterpolator()); 
a.setDuration(300); 
tv.setAnimation(a); 
tv.startAnimation(a); 

Puede jugar con ella para ver si se puede conseguir que se ajuste a sus necesidades.

+0

hey, estaba usando esto para colapsar el elemento de lista, pero cuando el usuario presiona deshacer necesito que el elemento vuelva. ¿De alguna forma podría revertir la animación? Intenté 'newHeight = (int) (mFromHeight * (1 + interpolatedTime));' Cambiar el signo negativo a + pero eso da un efecto extraño – Zen

+0

'interpolatedTime' interpola de 0 a 1, por lo que eliminar' 0 -' debería producir el efecto contrario. También tendrá que cambiar 'mFromHeight' (probablemente renombrado a' mToHeight') para inicializar a la altura natural de la vista. p.ej. 'this.mToHeight = view.getMeasuredHeight();' – devnate

+0

Una cosa: si la altura se establece en 0, la vista volverá a ocupar su altura completa (al menos con mi código), así que haga algo como 'mView.getLayoutParams(). height = Matemáticasmax (newHeight, 1); ' – bluewhile

0

El androide no actúan como HTML, cuando se cambia la anchura, la altura o visibilidad en una vista, las otras vistas no actualizan sus posiciones . Si necesita hacer eso, debe actualizar toda la vista de lista y sus vistas en el interior, de forma individual. Este es un código complejo para hacer.

+0

Incorrecto. Como puede ver en la respuesta @devnate, puede forzar las actualizaciones de los límites de Vista de manera bastante simple. – bluewhile

3

¿Volverá a utilizar el elemento cliqueado? Si no es así, entonces se podría

  1. Esperar a que la animación termine
  2. eliminar el elemento de donde se almacenan los datos subyacente
  3. continuación, llame al método notifyDataSetChanged() de su listadapter
+0

esto es correcto. utilice un oyente de animación adjunto a la animación para "onAnimationEnd" y luego haga lo sugerido. –

+0

Esto no responde a la pregunta: las vistas inferiores no se moverán hacia arriba ya que la vista de destino se escalará a nada, solo se ajustarán en su lugar una vez que la animación termine. – Tom

Cuestiones relacionadas