2012-02-09 33 views
17

Có cách nào để tạo hoạt ảnh cho nhiều chế độ xem cùng một lúc không?Hoạt ảnh đơn lẻ - Nhiều chế độ xem

Những gì tôi muốn làm là dịch hình ảnh động:

Tôi có 5 TextView và 4 dải màu (RelativeLayouts đơn giản với một nền). Khi bắt đầu các hoạt ảnh, các stips được xếp chồng lên nhau với TextViews trong một hàng ngang. Cuối cùng tôi muốn tất cả các TextView xếp chồng lên nhau giữa các dải:

enter image description here

Đây là một bản vẽ rất đơn giản, nhưng nó thể hiện những gì tôi muốn làm. Có cách nào để làm điều này với hình ảnh động hay tôi phải sử dụng hoạt ảnh canvas.

Trả lời

4

Tạo đối tượng hoạt ảnh của bạn, sau đó sử dụng startAnimation chung trên tất cả các chế độ xem cùng một lúc. Vì vậy, nó sẽ là một cái gì đó như thế này:

TranslateAnimation anim1; 
TranslateAnimation anim2; 
TranslateAnimation anim3; 

// Setup the animation objects 

public void startAnimations() 
{ 
    //... collect view objects 
    view1.startAnimation(anim1); 
    view2.startAnimation(anim2); 
    view3.startAnimation(anim3); 
} 

Chỉ cần lưu ý rằng các hình ảnh động hơn bạn đã diễn ra cùng một lúc, chậm hơn nó sẽ được.

+1

Sẽ không này khiến họ không được đồng bộ (không cần thiết ở đây) , đặc biệt là những cái bắt đầu sau này? – Matthew

+0

Không thực sự. Về cơ bản những gì xảy ra là khi bạn sử dụng 'startAnimation' trên một khung nhìn, nó bắt đầu vô hiệu hóa chính nó cho đến khi nó đến vị trí mong muốn. Khi bạn gọi nó trên tất cả các khung nhìn cùng một lúc, tất cả chúng sẽ gọi 'invalidate()' trên chính chúng, sau đó trên hình vẽ tiếp theo, mỗi khung nhìn sẽ được vẽ trong khung tiếp theo của chúng. Vì bạn đang gọi tất cả điều này trên chuỗi giao diện người dùng, không có hoạt ảnh nào sẽ bắt đầu cho đến khi bạn trở về từ phương thức đó. LƯU Ý: Sử dụng khung hoạt ảnh trước Honeycomb chỉ di chuyển phần trực quan của chế độ xem.Người dùng sẽ không thể nhấp vào nó. – DeeV

+0

Tôi áp dụng các hình động với anim1.setFillAfter (true); và sau đó thực sự di chuyển chế độ xem bằng cách sử dụng thông số bố cục? (Tôi chỉ nên thử nó, nhưng cuối của nó :) – Matthew

3

Tôi đã quản lý để chia sẻ một trường hợp Hoạt ảnh đơn lẻ trong một số Chế độ xem. Ít nhất với AlphaAnimation. Tôi đã có một ListView và một hình ảnh động sẽ được áp dụng cho một đứa trẻ cụ thể của tất cả các chế độ xem danh sách. Trong trường hợp của tôi, nên có thể cho các lượt xem 'tham gia' và 'rời' hoạt ảnh được chia sẻ bất kỳ lúc nào và nó không ảnh hưởng đến các chế độ xem động khác theo bất kỳ cách nào hoặc gây trở ngại cho hoạt ảnh đã chạy. Để đạt được điều này, tôi đã phải thực hiện một bản sao điều chỉnh của AlphaAnimation chứng khoán của Android. Trường hợp sử dụng của tôi khá đặc biệt, nhưng hãy để nó ở đây chỉ trong trường hợp ai đó phải đối phó với mục tiêu tương tự với ListView.

/** 
* This class is a copy of android's stock AlphaAnimation with two adjustments: 
* - fromAlpha, toAlpha and duration are settable at any time. 
* - reset() method can be blocked. Reason: view.setAnimation() calls animation's reset() method 
* which is not intended in our use case. 
* For every new list item view we call setAnimation once for it's life time 
* and animation should not be reset because it is shared by all list item views and may be in progress. 
*/ 
public class MutableAlphaAnimation extends Animation { 
    private float mFromAlpha; 
    private float mToAlpha; 
    private boolean resetBlocked; 

    public MutableAlphaAnimation() { 
    } 

    public void start(float fromAlpha, float toAlpha, long duration) { 
     mFromAlpha = fromAlpha; 
     mToAlpha = toAlpha; 
     setDuration(duration); 
     setStartTime(START_ON_FIRST_FRAME); 
    } 

    public void setResetBlocked(boolean resetBlocked) { 
     this.resetBlocked = resetBlocked; 
    } 

    @Override 
    public void reset() { 
     if (! resetBlocked) super.reset(); 
    } 

    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) { 
     final float alpha = mFromAlpha; 
     t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime)); 
    } 

    @Override 
    public boolean willChangeTransformationMatrix() { 
     return false; 
    } 

    @Override 
    public boolean willChangeBounds() { 
     return false; 
    } 
} 

Để thiết lập hình ảnh động này cho một người xem:

  animation.setResetBlocked(true); 
      view.setAnimation(animation); 
      animation.setResetBlocked(false); 

Và để bắt đầu một hình ảnh động (trước đây được thiết lập bởi setAnimation) HAI thứ phải được thực hiện:

 animation.start(0.0f, 1.0f, FADE_IN_DURATION); 

Và sau đó bạn phải gọi thủ công invalidate() trên mỗi chế độ xem bị ảnh hưởng bởi hoạt ảnh.

Phương thức startAnimation() không hợp lệ bình thường() cho bạn, nhưng setAnimation thì không. (đọc nhận xét trên phương thức View.setAnimation() trong các nguồn của Android).

49

Bạn có thể sử dụng ObjectAnimator cho hoạt cảnh xem nhiều như sau:

ArrayList<ObjectAnimator> arrayListObjectAnimators = new ArrayList<ObjectAnimator>(); //ArrayList of ObjectAnimators 

ObjectAnimator animY = ObjectAnimator.ofFloat(view, "y", 100f); 
arrayListObjectAnimators.add(animY); 

ObjectAnimator animX = ObjectAnimator.ofFloat(view, "x", 0f); 
arrayListObjectAnimators.add(animX); 
... 
ObjectAnimator[] objectAnimators = arrayListObjectAnimators.toArray(new ObjectAnimator[arrayListObjectAnimators.size()]); 
AnimatorSet animSetXY = new AnimatorSet(); 
animSetXY.playTogether(objectAnimators); 
animSetXY.setDuration(1000);//1sec 
animSetXY.start(); 
+2

Nhược điểm duy nhất là nó là mới kể từ phiên bản 11 (tổ ong) – Matthew

+3

Sử dụng chínoldandroids để mang lại API tất cả các cách trở lại 1.0 (http://nineoldandroids.com/) – Tushar

+0

+1 cho thấy làm thế nào để khởi động tất cả cùng nhau –

0

Bạn có thể sử dụng AnimationSet

AnimatorSet decSet2 = new AnimatorSet(); 
     decSet2.playTogether(
       ObjectAnimator.ofFloat(view, "x",dX), 
       ObjectAnimator.ofFloat(view, "y",dY), 
       ObjectAnimator.ofFloat(mTextCancel, "x",dX), 
       ObjectAnimator.ofFloat(mTextCancel, "y", dY), 
       ObjectAnimator.ofArgb(mBtnOne, "visibility", View.VISIBLE, View.GONE), 
       ); 
     decSet2.setDuration(0); 
     decSet2.start(); 
Các vấn đề liên quan