studio programacion para móviles libros gratis español edición desarrollo desarrollar curso aprende aplicaciones android animation view

para - manual programacion android español pdf



Animación de Android desplegable/vista adecuada (2)

Así que terminé haciéndolo con la ayuda de: https://stackoverflow.com/a/9112691/969325 . Si hubiera sido Android 3.0 ( http://developer.android.com/guide/topics/graphics/animation.html ) podría haber usado la animación de propiedades, pero no es así que tuve que hacerlo yo mismo.

Esto es lo que terminé con:

import android.view.View; import android.view.animation.Animation; import android.view.animation.Transformation; /** * Class for handling collapse and expand animations. * @author Esben Gaarsmand * */ public class ExpandCollapseAnimation extends Animation { private View mAnimatedView; private int mEndHeight; private int mType; /** * Initializes expand collapse animation, has two types, collapse (1) and expand (0). * @param view The view to animate * @param duration * @param type The type of animation: 0 will expand from gone and 0 size to visible and layout size defined in xml. * 1 will collapse view and set to gone */ public ExpandCollapseAnimation(View view, int duration, int type) { setDuration(duration); mAnimatedView = view; mEndHeight = mAnimatedView.getLayoutParams().height; mType = type; if(mType == 0) { mAnimatedView.getLayoutParams().height = 0; mAnimatedView.setVisibility(View.VISIBLE); } } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (interpolatedTime < 1.0f) { if(mType == 0) { mAnimatedView.getLayoutParams().height = (int) (mEndHeight * interpolatedTime); } else { mAnimatedView.getLayoutParams().height = mEndHeight - (int) (mEndHeight * interpolatedTime); } mAnimatedView.requestLayout(); } else { if(mType == 0) { mAnimatedView.getLayoutParams().height = mEndHeight; mAnimatedView.requestLayout(); } else { mAnimatedView.getLayoutParams().height = 0; mAnimatedView.setVisibility(View.GONE); mAnimatedView.requestLayout(); mAnimatedView.getLayoutParams().height = mEndHeight; } } } }

Ejemplo de uso:

import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class AnimationTestActivity extends Activity { private boolean mActive = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final Button animatedButton = (Button) findViewById(R.id.animatedButton); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ExpandCollapseAnimation animation = null; if(mActive) { animation = new ExpandCollapseAnimation(animatedButton, 1000, 1); mActive = false; } else { animation = new ExpandCollapseAnimation(animatedButton, 1000, 0); mActive = true; } animatedButton.startAnimation(animation); } }); } }

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:orientation="vertical" > <Button android:id="@+id/animatedButton" android:visibility="gone" android:layout_width="fill_parent" android:layout_height="50dp" android:text="@string/hello"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello"/> </LinearLayout>

Editar :

Medida wrap_content altura:

Así que para que esto funcione para wrap_content, medí la altura de la vista antes de comenzar la animación y luego usar esta altura medida como la altura real. A continuación se muestra el código para medir la altura de la vista y establecer esto como la nueva altura (supongo que la vista utiliza el ancho de la pantalla, cambiar de acuerdo con sus propias necesidades):

/** * This methode can be used to calculate the height and set it for views with wrap_content as height. * This should be done before ExpandCollapseAnimation is created. * @param activity * @param view */ public static void setHeightForWrapContent(Activity activity, View view) { DisplayMetrics metrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int widthMeasureSpec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec); int height = view.getMeasuredHeight(); view.getLayoutParams().height = height; }

Está bien, estoy tratando de hacer una correcta animación deslizante hacia abajo. La vista que se desliza hacia abajo debe empujar todas las vistas hacia abajo en un movimiento suave y nuevamente, cuando se desliza hacia arriba, todas las vistas deben seguir en un movimiento suave.

Lo que he intentado : En código:

LinearLayout lin = (LinearLayout)findViewById(R.id.user_list_container); setLayoutAnimSlidedownfromtop(lin, this); lin.addView(getLayoutInflater().inflate(R.layout.user_panel,null),0);

Y:

public static void setLayoutAnimSlidedownfromtop(ViewGroup panel, Context ctx) { AnimationSet set = new AnimationSet(true); Animation animation = new AlphaAnimation(0.0f, 1.0f); animation.setDuration(100); set.addAnimation(animation); animation = new TranslateAnimation( Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f ); animation.setDuration(500); set.addAnimation(animation); LayoutAnimationController controller = new LayoutAnimationController(set, 0.25f); panel.setLayoutAnimation(controller); }

Mi user_panel.xml:

<?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="40dp" android:orientation="vertical" > <ImageView android:layout_alignParentLeft="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/icon" /> </LinearLayout>

Principio del xml principal:

<LinearLayout android:id="@+id/user_list_container" android:layout_alignParentTop="true" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <LinearLayout android:id="@+id/container" android:layout_below="@+id/user_list_container" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="wrap_content">

El problema con el enfoque anterior es que cuando comienzo la animación, primero se crea el espacio vacío para la vista y luego la vista se desliza hacia abajo. Me gustaría que empuje lentamente todas las otras vistas hacia abajo en lugar de hacerlo en un solo movimiento.


Gracias Warpzit! Esa fue una respuesta muy útil. En mi caso, solo estaba tratando de animar vistas con altura que era wrap_content. Intenté activar la sugerencia de dos líneas, pero no funcionó en mi caso. (No pasé mucho tiempo persiguiendo por qué). Terminé usando una forma ligeramente modificada de ExpandCollapseAnimation de ExpandCollapseAnimation con su método estático para determinar la altura de la vista

En un poco más de detalle:

  1. setHeightForWrapContent() su método estático setHeightForWrapContent() en la clase ExpandCollapseAnimation .
  2. Llamo a setHeightForWrapContent() en el constructor ExpandCollapseAnimation para determinar correctamente la altura de la vista. Para hacer esto, tengo que pasar la actividad con el constructor.
  3. En el método applyTransformation() , cuando la vista finalmente se reduce a la altura cero, devuelvo la altura de la vista a wrap_content. Si no lo hace y cambia el contenido de la vista más adelante, cuando la expanda, la vista se expandirá a la altura determinada previamente.

El código está aquí:

public class ExpandCollapseAnimation extends Animation { private View mAnimatedView; private int mEndHeight; private int mType; public ExpandCollapseAnimation(View view, int duration, int type, Activity activity) { setDuration(duration); mAnimatedView = view; setHeightForWrapContent(activity, view); mEndHeight = mAnimatedView.getLayoutParams().height; mType = type; if(mType == 0) { mAnimatedView.getLayoutParams().height = 0; mAnimatedView.setVisibility(View.VISIBLE); } } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { super.applyTransformation(interpolatedTime, t); if (interpolatedTime < 1.0f) { if(mType == 0) { mAnimatedView.getLayoutParams().height = (int) (mEndHeight * interpolatedTime); } else { mAnimatedView.getLayoutParams().height = mEndHeight - (int) (mEndHeight * interpolatedTime); } mAnimatedView.requestLayout(); } else { if(mType == 0) { mAnimatedView.getLayoutParams().height = mEndHeight; mAnimatedView.requestLayout(); } else { mAnimatedView.getLayoutParams().height = 0; mAnimatedView.setVisibility(View.GONE); mAnimatedView.requestLayout(); mAnimatedView.getLayoutParams().height = LayoutParams.WRAP_CONTENT; // Return to wrap } } } public static void setHeightForWrapContent(Activity activity, View view) { DisplayMetrics metrics = new DisplayMetrics(); activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); int screenWidth = metrics.widthPixels; int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int widthMeasureSpec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.EXACTLY); view.measure(widthMeasureSpec, heightMeasureSpec); int height = view.getMeasuredHeight(); view.getLayoutParams().height = height; } }

Gracias de nuevo, Warpzit!