Trả lời

4

Tôi cũng đã xem xét vấn đề này. Cuối cùng tôi đã giải quyết nó bằng cách làm hoạt hóa thuộc tính weightsum của cha mẹ, nó hoạt động rất tốt nếu bạn có hai khung nhìn trong LinearLayout.

xem: Animating weightSum property using ObjectAnimator

Trong ví dụ dưới đây, nếu bạn animate weightSum 1,0-2,0, màn hình 2 sẽ animate độc ​​đáo vào xem.

<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

Cách tiếp cận này có một giới hạn mà bạn không thể tạo hiệu ứng độc đáo cho màn hình đầu tiên 0 trọng lượng. Bạn sẽ cần một weightSum lớn để làm điều đó nhưng sau đó các hình ảnh động sẽ nhanh hơn. – headsvk

+0

Bất kỳ cách nào điều này có thể được thực hiện ngược lại? animate xem bên trái biến mất và tái xuất hiện? –

22

Bạn chỉ cần sử dụng ObjectAnimator.

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

Vấn đề một là lớp Xem không có phương thức setWeight() (được yêu cầu bởi ObjectAnimator). Để giải quyết vấn đề này, tôi đã viết trình bao bọc đơn giản giúp lưu trữ hoạt ảnh cân nặng xem.

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

Sử dụng nó theo cách này:

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

Cảm ơn. Điều này làm việc hoàn hảo. – Stephen

+0

Cảm ơn 'view.getParent(). RequestLayout();'. – CoolMind

0

Một cách khác là sử dụng cũ Animation lớp, như mô tả trong https://stackoverflow.com/a/20334557/2914140. Trong trường hợp này, bạn có thể đồng thời thay đổi trọng số của một số Chế độ xem.

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

Lưu ý: Tôi không chắc chắn rằng đây là cách tốt nhất, nhưng tôi đã thử nó và nó làm việc tốt

Đơn giản chỉ cần sử dụng 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

Các vấn đề liên quan