Respuesta

4

He estado mirando esto también. Eventualmente lo resolví animando la propiedad weightsum del padre, que funciona muy bien si tienes dos vistas en LinearLayout.

ver: Animating weightSum property using ObjectAnimator

En el siguiente ejemplo, si se anima la weightSum de 1,0 a 2,0, de la pantalla 2 se animará muy bien a la vista.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/dual_pane" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="horizontal" 
    android:weightSum="1.0"> 

<!-- Screen 1 --> 
<LinearLayout 
    android:layout_width="0dp" 
    android:layout_height="match_parent" 
    android:background="#ff0000" 
    android:layout_weight="1"> 
</LinearLayout> 

<!-- Screen 2 --> 
<LinearLayout 
    android:layout_width="0dp" 
    android:layout_height="match_parent" 
    android:background="#ff6600" 
    android:layout_weight="1"> 
</LinearLayout> 
</LinearLayout> 
+1

Este enfoque tiene una limitación: no se puede animar muy bien la primera pantalla para 0 peso. Necesitarías un gran pesoSum para hacer eso pero luego la animación será más rápida. – headsvk

+0

¿Alguna manera de hacer esto al revés? animar la vista izquierda desapareciendo y reapareciendo? –

22

Simplemente puede usar ObjectAnimator.

ObjectAnimator anim = ObjectAnimator.ofFloat(
       viewToAnimate, 
       "weight", 
       startValue, 
       endValue); 
     anim.setDuration(2500); 
     anim.start(); 

El único problema es que la clase View tiene ningún método setWeight() (que es requerido por ObjectAnimator). Para resolver esto, escribí un contenedor simple que ayuda a visualizar la animación de peso del archivo.

public class ViewWeightAnimationWrapper { 
    private View view; 

    public ViewWeightAnimationWrapper(View view) { 
     if (view.getLayoutParams() instanceof LinearLayout.LayoutParams) { 
      this.view = view; 
     } else { 
      throw new IllegalArgumentException("The view should have LinearLayout as parent"); 
     } 
    } 

    public void setWeight(float weight) { 
     LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); 
     params.weight = weight; 
     view.getParent().requestLayout(); 
    } 

    public float getWeight() { 
     return ((LinearLayout.LayoutParams) view.getLayoutParams()).weight; 
    } 
} 

utilizarlo en esta forma:

ViewWeightAnimationWrapper animationWrapper = new ViewWeightAnimationWrapper(view); 
    ObjectAnimator anim = ObjectAnimator.ofFloat(animationWrapper, 
        "weight", 
        animationWrapper.getWeight(), 
        weight); 
      anim.setDuration(2500); 
      anim.start(); 
+0

Gracias. Esto funcionó perfectamente. – Stephen

+0

Gracias por 'view.getParent(). RequestLayout();'. – CoolMind

0

Otra forma es utilizar la vieja clase Animation, como se describe en https://stackoverflow.com/a/20334557/2914140. En este caso, puede cambiar simultáneamente los pesos de varias Vistas.

private static class ExpandAnimation extends Animation { 
    private final View[] views; 
    private final float startWeight; 
    private final float deltaWeight; 

    ExpandAnimation(View[] views, float startWeight, float endWeight) { 
     this.views = views; 
     this.startWeight = startWeight; 
     this.deltaWeight = endWeight - startWeight; 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     float weight = startWeight + (deltaWeight * interpolatedTime); 
     for (View view : views) { 
      LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.getLayoutParams(); 
      lp.weight = weight; 
      view.setLayoutParams(lp); 
     } 
     views[0].getParent().requestLayout(); 
    } 

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

Nota: No estoy seguro de que esta es la mejor manera, pero lo probé y está funcionando muy bien

Simplemente usando ValueAnimator

ValueAnimator m1 = ValueAnimator.ofFloat(0.2f, 0.5f); //fromWeight, toWeight 
m1.setDuration(400); 
m1.setStartDelay(100); //Optional Delay 
m1.setInterpolator(new LinearInterpolator()); 
m1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
     @Override 
     public void onAnimationUpdate(ValueAnimator animation) { 
      ((LinearLayout.LayoutParams) viewToAnimate.getLayoutParams()).weight = (float) animation.getAnimatedValue(); 
      viewToAnimate.requestLayout(); 
     } 

}); 
m1.start(); 

More About ValueAnimator

Cuestiones relacionadas