旋转图像。动画列表还是动画旋转? (Android)

问题描述:

我想创建一个旋转的进度图像,并想知道最佳的处理方式。我可以使它与动画列表一起工作,例如每100ms更改12张图像。这工作得很好,但它是相当繁琐的创建12个图片或每大小和分辨率:旋转图像。动画列表还是动画旋转? (Android)

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> 
<item android:drawable="@drawable/ic_loading_grey_on_black_01" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_02" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_03" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_04" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_05" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_06" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_07" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_08" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_09" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_10" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_11" android:duration="100" /> 
<item android:drawable="@drawable/ic_loading_grey_on_black_12" android:duration="100" /> 

我想,一个更简单的解决方案是每分辨率使用一个图像,而是将其旋转为每帧。在平台资源(android-sdk-windows/platforms ...)中,我在文件drawable/search_spinner.xml中发现了一个名为动画旋转的东西,但是如果我复制代码,请获取编译器错误,抱怨android:framesCount和android: frameDuration(谷歌的API 2.2在Eclipse):

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" 
android:drawable="@drawable/spinner_black_20" 
android:pivotX="50%" 
android:pivotY="50%" 
android:framesCount="12" 
android:frameDuration="100" /> 

我已经使用重复旋转动画(使用动画资源文件夹)也尝试过,但其实我更喜欢的动画列表版本的外观。

解决此问题的建议方法是什么?

你必须创建一个可绘制的XML文件,如下图所示:

代码:

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" 
android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0" 
android:toDegrees="360" android:drawable="@drawable/imagefile_to_rotate" /> 
+2

它怎么不旋转? – 2014-06-19 16:43:18

+0

它不适用于某些设备。请使用rotage代替 – vuhung3990 2015-07-22 09:07:15

在这里看到的例子 http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/index.html

明确: 进度条

  1. 增量 演示大小旋转进度指示器,可以单位递增或递减。
  2. 平滑 演示大型和小型连续旋转进度指示器,用于指示通用“繁忙”消息。
  3. 对话框 演示ProgressDialog,一个托管进度条的弹出对话框。这个例子演示了确定和不确定的进度指标。
  4. 标题栏 通过设置WindowPolicy的进度指示器功能演示一个带有进度指示器的活动屏幕。

SACPK的解决方案绝对有效。另一种解决方案可以像使用问题那样使用<animated-rotate>,并且为编译器所抱怨的那些人删除android:framesCount="12" android:frameDuration="100"属性。它甚至可以用于我的8幅图像。

但是,我没有带想通了如何控制动画:(速度。

Rotate drawable由普利文认为不会给你帧数的控制。让我们假设你想实现一个自定义的加载它由8个部分:

gif_icon

使用animation-list方法,你需要创建通过手动45*frameNumber度旋转8帧。另外,您也可以使用第一帧,将旋转动画吧:

progress_icon

文件res/anim/progress_anim.xml

<?xml version="1.0" encoding="utf-8"?> 
<rotate 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fromDegrees="0" 
    android:toDegrees="360" 
    android:pivotX="50%" 
    android:pivotY="50%" 
    android:repeatCount="infinite" /> 

文件MainActivity.java

Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim); 
a.setDuration(1000); 
imageView.startAnimation(a); 

这将给你流畅的动画,而不是8阶梯。为了解决这个问题,我们需要实现自定义插值:

a.setInterpolator(new Interpolator() { 
    private final int frameCount = 8; 

    @Override 
    public float getInterpolation(float input) { 
     return (float)Math.floor(input*frameCount)/frameCount; 
    } 
}); 

您也可以创建一个自定义窗口小部件:

文件res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="ProgressView"> 
     <attr name="frameCount" format="integer"/> 
     <attr name="duration" format="integer" /> 
    </declare-styleable> 
</resources> 

文件ProgressView.java

public class ProgressView extends ImageView { 

    public ProgressView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     setAnimation(attrs); 
    } 

    public ProgressView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setAnimation(attrs); 
    } 

    public ProgressView(Context context) { 
     super(context); 
    } 

    private void setAnimation(AttributeSet attrs) { 
     TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressView); 
     int frameCount = a.getInt(R.styleable.ProgressView_frameCount, 12); 
     int duration = a.getInt(R.styleable.ProgressView_duration, 1000); 
     a.recycle(); 

     setAnimation(frameCount, duration); 
    } 

    public void setAnimation(final int frameCount, final int duration) { 
     Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim); 
     a.setDuration(duration); 
     a.setInterpolator(new Interpolator() { 

      @Override 
      public float getInterpolation(float input) { 
       return (float)Math.floor(input*frameCount)/frameCount; 
      } 
     }); 
     startAnimation(a); 
    } 
} 

文件activity_main.xml

<com.example.widget.ProgressView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/ic_progress" 
    app:frameCount="8" 
    app:duration="1000"/> 

文件res/anim/progress_anim.xml:以上

+0

太棒了,非常感谢你 – 2013-02-25 14:27:27

+3

“谢谢!”,“我也是!”, – Cephron 2014-04-02 21:46:20

+0

我无法通过使用android:visibility =“invisible”隐藏progressview吗? – Prateek 2014-06-09 11:04:57

我发现vokilam的答案是创建一个不错的阶梯/交错动画最好的一家上市。我去了他的最终建议,并做了一个自定义小部件,我遇到的唯一问题是设置可见性将无法工作,因为它是动画,因此将始终可见...

我调整了他的代码(ProgressView.java我改名StaggeredProgress.java)是这样的:

public class StaggeredProgress extends ImageView { 

private Animation staggered; 

public StaggeredProgress(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    setAnimation(attrs); 
} 

public StaggeredProgress(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    setAnimation(attrs); 
} 

public StaggeredProgress(Context context) { 
    super(context); 
} 

private void setAnimation(AttributeSet attrs) { 
    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StaggeredProgress); 
    int frameCount = a.getInt(R.styleable.StaggeredProgress_frameCount, 12); 
    int duration = a.getInt(R.styleable.StaggeredProgress_duration, 1000); 
    a.recycle(); 

    setAnimation(frameCount, duration); 
} 

public void setAnimation(final int frameCount, final int duration) { 
    Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim); 
    a.setDuration(duration); 
    a.setInterpolator(new Interpolator() { 

     @Override 
     public float getInterpolation(float input) { 
      return (float)Math.floor(input*frameCount)/frameCount; 
     } 
    }); 
    staggered = a; 
    //startAnimation(a); 
} 

@Override 
public void setVisibility(int visibility) { 
    super.setVisibility(visibility); 
    if(visibility == View.VISIBLE) 
     startAnimation(staggered); 
    else 
     clearAnimation(); 

} 


} 

这种方式设置视图的可视性启动和停止动画嘀......再次感谢给vokilam!