risposta

4

Ho visto anche questo. Alla fine l'ho risolto animando la proprietà weightsum del genitore, che funziona molto bene se hai due viste in un LinearLayout.

vedere: Animating weightSum property using ObjectAnimator

Nell'esempio qui sotto, se animate la weightSum 1,0-2,0, Schermo 2 animerà ben in 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

Questo approccio ha una limitazione a cui non è possibile animare piacevolmente il primo schermo 0 peso. Avresti bisogno di un grande weightSum per farlo, ma poi l'animazione sarà più veloce. – headsvk

+0

In qualsiasi modo questo potrebbe essere fatto in senso inverso? animare la vista sinistra scomparendo e riapparendo? –

22

È sufficiente utilizzare ObjectAnimator.

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

L'unico problema è che Vista classe ha alcun metodo setWeight() (che è richiesta da ObjectAnimator). Per risolvere questo problema ho scritto un semplice wrapper che aiuta ad archiviare l'animazione del peso della vista.

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; 
    } 
} 

utilizzarlo in questo modo:

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

Grazie. Questo ha funzionato perfettamente. – Stephen

+0

Grazie per 'view.getParent(). RequestLayout();'. – CoolMind

0

Un altro modo è quello di utilizzare vecchio Animation di classe, come descritto in https://stackoverflow.com/a/20334557/2914140. In questo caso è possibile modificare contemporaneamente pesi di diverse viste.

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: Non sono sicuro che questo è il modo migliore, ma ho provato e che sta funzionando benissimo

Semplicemente 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

Problemi correlati