回答

4

我一直在看这个。最终,我通过动画父代的权重属性来解决它,如果您在LinearLayout中有两个视图,这非常好。

看到: Animating weightSum property using ObjectAnimator

在下面的例子中,如果从1.0动画weightSum到2.0,屏幕2将很好地动画进入视野。

<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

这种方法有一个限制,你不能很好地将第一个屏幕设置为动画0重量。你需要大量的重量来做到这一点,但动画会更快。 – headsvk 2016-05-23 13:20:41

+0

任何方式可以做到相反?使左视图动画消失并重现? – 2017-02-28 00:08:37

22

您可以简单地使用ObjectAnimator。

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

的一个问题是,查看类没有setWeight()方法(其由ObjectAnimator需要)。为了解决这个问题,我写了一个简单的包装器,它可以帮助存档视图加权动画

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

使用它以这种方式:

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

谢谢。这工作完美。 – Stephen 2016-02-18 22:51:19

+0

感谢'view.getParent()。requestLayout();'。 – CoolMind 2017-10-03 18:45:40

0

另一种方法是使用旧Animation类,如https://stackoverflow.com/a/20334557/2914140描述。在这种情况下,您可以同时更改多个视图的权重。

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

注:我不知道,这是最好的方式,但我想它和它的正常工作

只需用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