Java 动态更改自定义视图上的动画速度
首先,谈到android,我不是一个神童。把它拿出来 我需要一个图像不断旋转,当我提供输入时,更新旋转速度。目前,每次单击按钮时,我都会创建一个新的ObjectAnimator。这将从文本字段中获取一个值,并将其作为持续时间应用于ObjectAnimator。这确实有效,但它会在每次单击按钮时重置动画。我需要动画平滑地改变速度,每次我点击 我觉得在这里使用ObjectAnimator可能是错误的,但我不知道还有什么更好的选择 需要注意的一点是,我的API最大值为18Java 动态更改自定义视图上的动画速度,java,android,android-animation,Java,Android,Android Animation,首先,谈到android,我不是一个神童。把它拿出来 我需要一个图像不断旋转,当我提供输入时,更新旋转速度。目前,每次单击按钮时,我都会创建一个新的ObjectAnimator。这将从文本字段中获取一个值,并将其作为持续时间应用于ObjectAnimator。这确实有效,但它会在每次单击按钮时重置动画。我需要动画平滑地改变速度,每次我点击 我觉得在这里使用ObjectAnimator可能是错误的,但我不知道还有什么更好的选择 需要注意的一点是,我的API最大值为18 public class S
public class SpinActivity extends Activity {
private CustomView customView;
private Button button;
private EditText input;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spin_activity);
//Init Variables
customView = (CustomView) findViewById(R.id.spinner_custom_view);
button = (Button) findViewById(R.id.spinner_button);
input = (EditText) findViewByIdR.id.speed);
//Set up the button to animate the custom view
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
float fSpeed = Float.parseFloat(txtSpeed.getText().toString());
customView.animateBitmap(fSpeed);
}
});
}
}//末端脊柱活动
公共类CustomView扩展了视图{
private static final String TAG = CustomView.class.getSimpleName();
private Bitmap dialSpeedOuter;
private Context context;
private FrameLayout activityFrame;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (dialSpeedOuter == null) {
BitmapFactory.Options vmOptions = new BitmapFactory.Options();
vmOptions.inDensity = 800;
vmOptions.inJustDecodeBounds = false;
dialSpeedOuter = BitmapFactory.decodeResource(context.getResources(), R.drawable.spinner, vmOptions);
}
}
public void animateBitmap(long speed) {
long spinDuration = speed; //sets duration in ms
ObjectAnimator spin = ObjectAnimator.ofFloat(this , "rotation", 0.0f, 360.0f);
spin.setRepeatMode(ObjectAnimator.RESTART);
spin.setRepeatCount(ObjectAnimator.INFINITE);
spin.setInterpolator(new LinearInterpolator());
spin.setDuration(spinDuration);
spin.start();
}
}//end CustomView对象animator将比使用画布手动处理视图旋转更易于使用 为了简单起见,我在默认的Android应用程序项目(最新的一个有这个片段的项目)中编写了自己的小演示,其中时间减少了1/2。您应该能够根据需要调整代码。(你也不需要把它放在集合中。我只是把它放在那里,因为我从其他代码中复制了一些代码,但在测试之前忘了把它拿出来)
除了我的评论之外,还有一些类似的东西:
public class CustomView extends View {
private static float ROATION_ANGLE_INCREMENT = 1;
private static float ROATION_SPEED_INCREMENT = 10;
private Thread animationThread;
private long sleepTime = 100;
private float rotationAngle = 0;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.rotate(rotationAngle, canvas.getWidth()/2, canvas.getHeight()/2));
super.onDraw(canvas);
canvas.restore();
}
public void startRotation(){
isActive = true;
animationThread = new Thread(new Runnable(){
public void run() {
while(isActive){
try{
rotationAngle = (rotationAngle + ROATION_ANGLE_INCREMENT) % 360;
CustomView.this.postInvalidate();
Thread.sleep(sleepDelay);
}
catch(Exception e){ }
}
}
});
animationThread.start();
}
private void onIncreaseSpeed(){
sleepTime -= ROTATION_SPEED_INCREMENT;
}
private void stop(){
try{
isActive = false;
animationThread.stop();
}
catch(Exception e){}
}
}
我在没有测试或编译器的情况下就这么做了,所以你肯定要对它和所有默认值进行一些调整,以匹配你想要的结果
您可能还希望使其扩展布局,而不是视图,并使视图位于其中,以便图像不会被切断。您可以使用动画可绘制,它允许您提供帧图像+帧间动画所需的时间纠正我的错误,但动画可绘制不是仅用于帧动画吗?我只需要旋转一个图像。听起来像是一个图像在旋转,而不是一组图像,所以这不适用于。。。您是否尝试过不使用任何动画对象,并通过视图的onDraw方法手动处理旋转(即使用画布旋转显示的可绘制对象),然后使用单独的线程处理“动画”(即通过减少无效调用之间的睡眠时间来增加动画速度)有一个帖子,一个家伙抱怨说,这种类型的动画在屏幕旋转时做了奇怪的事情。在画布上绘制了多幅图像。在android中,你永远不应该睡眠线程。您应该改为使用具有延迟后操作的处理程序。另外,在执行run方法之前(调度另一个处理程序),您必须检查活动是否正在完成,因为如果正在完成,可能会导致崩溃-该方法是“isFinishing()”@LenaBru您能告诉我您在哪里读到“android中的从不睡眠线程”,因为这听起来很可笑。是的,使用处理程序的postDelayed函数是一种选择,但这并不意味着它是唯一的选择,也不是最好的选择。在这种情况下,Thread.sleep()可以正常工作。至于你读到的另一篇文章,其中画了多幅图像:这与画布无关,与错误使用画布的人有关。
public class CustomView extends View {
private static float ROATION_ANGLE_INCREMENT = 1;
private static float ROATION_SPEED_INCREMENT = 10;
private Thread animationThread;
private long sleepTime = 100;
private float rotationAngle = 0;
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.rotate(rotationAngle, canvas.getWidth()/2, canvas.getHeight()/2));
super.onDraw(canvas);
canvas.restore();
}
public void startRotation(){
isActive = true;
animationThread = new Thread(new Runnable(){
public void run() {
while(isActive){
try{
rotationAngle = (rotationAngle + ROATION_ANGLE_INCREMENT) % 360;
CustomView.this.postInvalidate();
Thread.sleep(sleepDelay);
}
catch(Exception e){ }
}
}
});
animationThread.start();
}
private void onIncreaseSpeed(){
sleepTime -= ROTATION_SPEED_INCREMENT;
}
private void stop(){
try{
isActive = false;
animationThread.stop();
}
catch(Exception e){}
}
}