2011-01-10 64 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>