2011-01-10 61 views
7

是否有可能創建具有某種動畫的drawable,無論是逐幀動畫,旋轉等,它被定義爲一個xml drawable,並且可以用一個Drawable對象表示,而不必處理代碼中的動畫?是否可以繪製動畫?

我在想如何使用它: 我有一個列表,列表中的每個項目可能在某個時候發生了一些變化。當它發生時,我想要有一個類似於不確定的ProgressBar的旋轉進度動畫。因爲在屏幕上也可能有幾個我認爲如果他們都共享相同的Drawable,他們只需要在內存中的一個實例,他們的動畫就會被同步,所以你不會在各個點上有一堆旋轉對象在旋轉動畫中。

我不重視這種方法。我只是試圖想到最有效的方式來顯示幾個旋轉進度動畫,並理想地將它們同步在一起,以使它們在外觀上保持一致。

感謝

針對Sybiam的回答是:

我試圖實現一個RotateDrawable但不轉動。

這裏是我的xml的繪製迄今:

<?xml version="1.0" encoding="utf-8"?> 
<rotate xmlns:android="http://schemas.android.com/apk/res/android" 
android:drawable="@drawable/my_drawable_to_rotate" 
android:fromDegrees="0" 
android:toDegrees="360" 
android:pivotX="50%" 
android:pivotY="50%" 
android:duration="800" 
android:visible="true" /> 

我已經使用繪製作爲的ImageView的src和背景,並嘗試兩種方式只生產非旋轉圖像。

是否有東西需要啓動圖像旋轉?

+0

結帳http://stackoverflow.com/a/30901885/1052261 – 2016-02-11 10:30:08

回答

1

您可以從研究API Demos項目中的ProgressBar2開始(它可作爲SDK的一部分提供)。特別要注意R.layout.progressbar_2

7

​​

你走了!而這一個爲RotateDrawable。我相信從文件來看,它應該是相當緊張的。您可以在xml文件中定義所有內容,並將視圖的背景設置爲可繪製的xml。 /drawable/myrotate.xml - > @ drawable/myrotate

編輯: 這是我在這裏找到的答案。 Drawable Rotating around its center Android

編輯2: 你是對的RotateDrawable似乎打破了。我不知道我也嘗試過。我還沒有成功製作動畫。但我確實成功地旋轉了它。你必須使用setLevel來旋轉它。雖然看起來不太有用。我瀏覽了代碼,RotateDrawable甚至沒有誇大動畫的持續時間,當前的旋轉似乎奇怪地使用該級別作爲旋轉的度量。我相信你必須在AnimationDrawable中使用它,但在這裏再次使用它。它只是爲我而墜毀。我尚未使用該功能,但計劃在未來使用該功能。我瀏覽了網頁,並且RotateDrawable似乎幾乎和每個Drawable對象都沒有文檔一樣。

+0

我想我的運氣與RotateDrawable和它沒有動畫。更多細節在我原來的問題。任何關於我在做什麼錯的想法? – cottonBallPaws 2011-01-13 00:40:02

+0

你開始動畫了嗎? – 2011-01-13 08:24:08

+1

因此,RotateDrawable必須被編程啓動?我想這種嘗試在xml中處理它的目的是失敗的。你會如何開始呢? – cottonBallPaws 2011-01-17 03:01:33

15

是的!我通過閱讀ProgressBar代碼發現的(未記錄的)密鑰是,您必須撥打中的Drawable.setLevel()以使<rotate>事情發揮作用。該ProgressBar的工作是這樣的(省略額外不重要的代碼):

提拉XML:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
     <rotate 
      android:drawable="@drawable/spinner_48_outer_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="0" 
      android:toDegrees="1080" /> 
    </item> 
    <item> 
     <rotate 
      android:drawable="@drawable/spinner_48_inner_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="720" 
      android:toDegrees="0" /> 
    </item> 
</layer-list> 

onDraw()

Drawable d = getDrawable(); 
    if (d != null) 
    { 
     // Translate canvas so a indeterminate circular progress bar with 
     // padding rotates properly in its animation 
     canvas.save(); 
     canvas.translate(getPaddingLeft(), getPaddingTop()); 

     long time = getDrawingTime(); 

     // I'm not sure about the +1. 
     float prog = (float)(time % ANIM_PERIOD+1)/(float)ANIM_PERIOD; 
     int level = (int)(MAX_LEVEL * prog); 
     d.setLevel(level); 
     d.draw(canvas); 

     canvas.restore(); 

     ViewCompat.postInvalidateOnAnimation(this); 
    } 

MAX_LEVEL是一個常數,並且始終10000(根據文檔)。 ANIM_PERIOD是以毫秒爲單位的動畫期間。

不幸的是,由於您需要修改onDraw(),因此您不能只將該繪圖放入ImageView,因爲ImageView永遠不會改變繪圖級別。但是,您可能可以從以外的更改ImageView的可繪製級別。 ProgressBar(ab)使用AlphaAnimation來設置級別。所以你會這樣做:

mMyImageView.setImageDrawable(myDrawable); 

ObjectAnimator anim = ObjectAnimator.ofInt(myDrawable, "level", 0, MAX_LEVEL); 
anim.setRepeatCount(ObjectAnimator.INFINITE); 
anim.start(); 

它可能會工作,但我沒有測試過它。

編輯

其實是有一個ImageView.setImageLevel()方法,所以它可能是那樣簡單:

ObjectAnimator anim = ObjectAnimator.ofInt(myImageVew, "ImageLevel", 0, MAX_LEVEL); 
anim.setRepeatCount(ObjectAnimator.INFINITE); 
anim.start(); 
2

這是可能的方式(尤其是有用的,當你有一個可繪製的地方設置和需要動畫它)。這個想法是包裝drawable並用動畫來裝飾它。就我而言,我不得不旋轉,所以下面你可以找到簡單的實現:

public class RotatableDrawable extends DrawableWrapper { 

    private float rotation; 
    private Rect bounds; 
    private ObjectAnimator animator; 
    private long defaultAnimationDuration; 

    public RotatableDrawable(Resources resources, Drawable drawable) { 
     super(vectorToBitmapDrawableIfNeeded(resources, drawable)); 
     bounds = new Rect(); 
     defaultAnimationDuration = resources.getInteger(android.R.integer.config_mediumAnimTime); 
    } 

    @Override 
    public void draw(Canvas canvas) { 
     copyBounds(bounds); 
     canvas.save(); 
     canvas.rotate(rotation, bounds.centerX(), bounds.centerY()); 
     super.draw(canvas); 
     canvas.restore(); 
    } 

    public void rotate(float degrees) { 
     rotate(degrees, defaultAnimationDuration); 
    } 

    public void rotate(float degrees, long millis) { 
     if (null != animator && animator.isStarted()) { 
      animator.end(); 
     } else if (null == animator) { 
      animator = ObjectAnimator.ofFloat(this, "rotation", 0, 0); 
      animator.setInterpolator(new AccelerateDecelerateInterpolator()); 
     } 
     animator.setFloatValues(rotation, degrees); 
     animator.setDuration(millis).start(); 
    } 

    @AnimatorSetter 
    public void setRotation(float degrees) { 
     this.rotation = degrees % 360; 
     invalidateSelf(); 
    } 

    /** 
    * Workaround for issues related to vector drawables rotation and scaling: 
    * https://code.google.com/p/android/issues/detail?id=192413 
    * https://code.google.com/p/android/issues/detail?id=208453 
    */ 
    private static Drawable vectorToBitmapDrawableIfNeeded(Resources resources, Drawable drawable) { 
     if (drawable instanceof VectorDrawable) { 
      Bitmap b = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); 
      Canvas c = new Canvas(b); 
      drawable.setBounds(0, 0, c.getWidth(), c.getHeight()); 
      drawable.draw(c); 
      drawable = new BitmapDrawable(resources, b); 
     } 
     return drawable; 
    } 
} 

,你可以用它像這樣(旋轉工具欄導航圖標360度):

backIcon = new RotatableDrawable(getResources(), toolbar.getNavigationIcon().mutate()); 
toolbar.setNavigationIcon(backIcon); 
backIcon.rotate(360); 

它不該「T很難添加將旋轉它不確定(setRepeatMode INFINITE for animator

0
private ValueAnimator rotateDrawable(RotateDrawable drawable, int fromDegree, int toDegree) { 
    drawable.setFromDegrees(fromDegree); 
    drawable.setToDegrees(toDegree); 
    return ObjectAnimator.ofInt(drawable, "level", 0, 10000); 
} 

水平的方法是從0到100000。interpulting值的實際動畫值由設置方法設置

0

可以使用stateListAnimator

<ImageView 
     android:id="@+id/your_id" 
     android:layout_width="200dp" 
     android:layout_height="200dp" 
     android:src="@drawable/your_drawable" 
     android:stateListAnimator="@anim/bounce" /> 

和彈跳

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 

    android:interpolator="@android:anim/bounce"> 
    <translate 
     android:duration="900" 

     android:fromXDelta="100%p" 
     android:toXDelta="0%p" /> 
</set>