2011-10-26 20 views
39

Ok, do đó, tôi kiểm tra ra http://android-developers.blogspot.com/2011/02/animation-in-honeycomb.htmlObjectAnimator động LinearLayout rộng

Ông nói rằng bạn có thể làm động tài sản của một đối tượng trong một thời gian nhất định. Và tôi đã cố gắng di chuyển xung quanh các đối tượng và nó có vẻ tốt. Tôi gặp phải một vấn đề khi tôi thay đổi chiều rộng của LinearLayout. Tôi nhận điều này:

10-26 14:51:27.190: E/PropertyValuesHolder(12681): Couldn't find setter/getter for  property width with value type float 

Sau đó, tôi đã cố gắng mở rộng LinearLayout, với "myWidth"

public void setMyWidth(int myWidth) { 
    LinearLayout.LayoutParams params = (LayoutParams) getLayoutParams(); 
    params.weight = myWidth; 
    setLayoutParams(params); 
    requestLayout(); 
    this.myWidth = myWidth; 
} 

Không may mắn. Sau đó, tôi đã cố gắng thay đổi LayoutParams.width, hóa ra chiều rộng và chiều cao là các thuộc tính công khai duy nhất trong lịch sử java, và ObjectAnimator cần getter và setter. Không may mắn. Tôi xin lỗi khi nói rằng tôi cũng đã cố gắng mở rộng LayoutParams ... mà không có may mắn.

Bất kỳ ai đã bắt đầu làm một việc như vậy? Tôi đã sử dụng android.view.animation cũ và tôi đã có được những gì tôi muốn, nhưng tôi tò mò về tương lai.

+0

Thật không may, tôi có một vấn đề tương tự. Thay vì làm động viên chiều rộng, tôi đã thử làm động lực cho weightSum (mà DOES có getter/setter) để đạt được hiệu quả tương tự. Có lẽ bạn có thể thử một cái gì đó tương tự để đạt được những gì bạn muốn, nhưng tôi không thể làm cho nó hoạt động: http://stackoverflow.com/questions/8341745/animating-weightsum-property-using-objectanimator. Tôi sẽ giữ cho bạn đăng nếu tôi có một số kết quả – Entreco

Trả lời

19

Đối với những gì nó đáng giá. Sau khi bạn thay đổi chiều rộng trên các tham số layout, bạn phải đặt lại đối tượng params layout.

private class WidthEvaluator extends IntEvaluator { 

    private View v; 
    public WidthEvaluator(View v) { 
     this.v = v; 
    } 

    @Override 
    public Object evaluate(float fraction, Object startValue, Object endValue) { 
     int num = (Integer)super.evaluate(fraction, startValue, endValue); 
     ViewGroup.LayoutParams params = v.getLayoutParams(); 
     params.width = num; 
     v.setLayoutParams(params); 
     return num; 
    } 
} 

// your client code 
ValueAnimator.ofObject(new WidthEvaluator(box), box.getWidth(), v.getWidth()).start(); 
+3

Để thực hiện công việc này với chínOldAndroids, hãy thay đổi chữ ký phương thức đánh giá để sử dụng Integer thay cho Object. 'public Integer assessment (phần lẻ, Integer startValue, Integer endValue)' – loeschg

+0

Không sử dụng các bộ đánh giá để thực hiện các thay đổi của khung nhìn. Thay vào đó hãy thêm 'AnimatorUpdateListener'. –

109

Trong tình huống mà ở đó không phải là một tài sản đơn giản getter/setter bạn nên sử dụng ValueAnimator và thực hiện các hình ảnh động bằng tay.

Giả sử:

  • v là quan điểm bạn đang tạo hiệu ứng động
  • END_WIDTH được chiều rộng mục tiêu của quan điểm tính theo pixel.
  • DURATION là độ dài mong muốn của hoạt ảnh theo mili giây.

Mã của bạn nên tìm một cái gì đó như thế này:

ValueAnimator anim = ValueAnimator.ofInt(v.getMeasuredWidth(), END_WIDTH); 
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
     @Override 
     public void onAnimationUpdate(ValueAnimator valueAnimator) { 
      int val = (Integer) valueAnimator.getAnimatedValue(); 
      ViewGroup.LayoutParams layoutParams = v.getLayoutParams(); 
      layoutParams.width = val; 
      v.setLayoutParams(layoutParams); 
     } 
    }); 
    anim.setDuration(DURATION); 
    anim.start(); 
+0

nhược điểm, từ 11 trở đi ... – desgraci

+2

Bạn có thể sử dụng http://nineoldandroids.com/ cho các phiên bản cũ hơn. – lordmegamax

+0

Trả lời rất tốt, cảm ơn bạn! – CyberDandy

6

Bạn đã thực hiện một sai lầm

params.weight = myWidth; 

Tôi nghĩ rằng đó là params.width không params.weight

1

Tôi nghĩ rằng một cách tốt hơn để thực hiện điều này wou ld là sử dụng thuộc tính scaleX và scaleY của View, được định nghĩa tất cả các cách trong lớp View, vì vậy nó sẽ hợp lệ với bất kỳ khung nhìn hoặc bố cục thực tế nào.

Ví dụ, hãy xem xét này

ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(MyLinearLayout,"ScaleX",0,1); 
objectAnimator.setDuration(300); 
objectAnimator.start(); 

Nó hoạt động.

+4

Không, nó không hoạt động. Quy mô này, tức là trải dài, chế độ xem, cách khác với việc phóng to, giữ nguyên tỷ lệ nội dung của chế độ xem. –

5

Tôi đã tạo một thư viện nhỏ ViewPropertyObjectAnimator có thể làm điều đó một cách rất đơn giản (và sử dụng cách tiếp cận tương tự với đề xuất này bởi Tomer Weller).

Bạn có thể đạt được hoạt hình này với (giả sử các mLinearLayout là hoạt hình ViewmEndWidth là giá trị cuối cùng của chiều rộng View's):

ViewPropertyObjectAnimator.animate(mLinearLayout).width(mEndWidth).start(); 
+0

Thư viện đẹp, @Bartosz! –

+0

Cảm ơn @StephenKaiser :)! Nó khá đơn giản nhưng rất hữu ích. –

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