Android绘制旋转动画方法详解
作者:吃橘子的季节呢 发布时间:2021-11-30 20:11:07
标签:Android,旋转,动画
1、准备工作
首先需要有一个用于旋转的图片
需要考虑如何开始、结束、加速、减速
2、加速减速原理
本次的动画采用RotateAnimation,初始化需要的参数如下
public RotateAnimation(float fromDegrees,float toDegrees,int pivotXType,float pivotXValue,int pivotYType, float pivotYValue) {
mFromDegrees = fromDegrees;//开始角度
mToDegrees = toDegrees;//结束角度
mPivotXValue = pivotXValue;//确定x轴坐标的类型
mPivotXType = pivotXType;//x轴的值,0.5f表明是以自身这个控件的一半长度为x轴
mPivotYValue = pivotYValue;//确定y轴坐标的类型
mPivotYType = pivotYType;//y轴的值,0.5f表明是以自身这个控件的一半长度为y轴
initializePivotPoint();
}
所谓旋转动画,在本质上就是在如上的对象初始化之后,规定在一定的周期内旋转
所谓加速,本质上就是在设定好的周期内变换旋转角度
或者修改周期,在预设周期内旋转一定角度
总之,角度和周期一定会变化一个,就可以决定动画的快慢。
如: 从 2秒内旋转360度 到 1秒内旋转360度 就是一种加速,
从 2秒内旋转360度 到 2秒内旋转720度 也是一种加速。
反之就是减速。
3、初始化
RotateAnimation rotate = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setInterpolator(new LinearInterpolator());
rotate.setDuration(2000);//设置动画持续周期
rotate.setRepeatCount(-1);//设置重复次数
// rotate.setFillAfter(true);//动画执行完后是否停留在执行完的状态
rotate.setStartOffset(10);//执行前的等待时间
4、开始
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fan.startAnimation(rotate);
}
});
5、加速
首先需要创建全局变量
private int duration=2000;
加速样例
accelerate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (duration>10){
duration/=2;//周期除2角度不变加速(需要考虑极端,所以加一个判断)
}
rotate.setDuration(duration);//设置周期
fan.startAnimation(rotate);//开始旋转
}
});
6、减速
decelerate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (duration<10000){
duration*=2;//周期乘2角度不变减速(需要考虑极端,所以加一个判断)
}
rotate.setDuration(duration);//设置周期
fan.startAnimation(rotate);//开始旋转
}
});
7、停止
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fan.clearAnimation(); //停止
}
});
8、项目源码
Layout部分
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DEECFA"
tools:context=".MainActivity">
<RelativeLayout
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:id="@+id/relativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@mipmap/border"
tools:layout_editor_absoluteX="566dp"
tools:layout_editor_absoluteY="132dp">
<ImageView
android:id="@+id/fan"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@mipmap/fan"
tools:layout_editor_absoluteX="552dp"
tools:layout_editor_absoluteY="122dp" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="150dp">
<Button
android:id="@+id/start"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@mipmap/border"
android:text="开始"
tools:layout_editor_absoluteX="525dp"
tools:layout_editor_absoluteY="596dp" />
<Button
android:id="@+id/accelerate"
android:layout_marginLeft="100dp"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@mipmap/border"
android:text="加速"
tools:layout_editor_absoluteX="650dp"
tools:layout_editor_absoluteY="596dp" />
<Button
android:layout_marginLeft="100dp"
android:id="@+id/decelerate"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@mipmap/border"
android:text="减速"
tools:layout_editor_absoluteX="795dp"
tools:layout_editor_absoluteY="596dp" />
<Button
android:id="@+id/stop"
android:layout_marginLeft="100dp"
android:layout_width="60dp"
android:layout_height="60dp"
android:background="@mipmap/border"
android:text="结束"
tools:layout_editor_absoluteX="950dp"
tools:layout_editor_absoluteY="596dp" />
</LinearLayout>
<ImageView
android:layout_centerVertical="true"
android:layout_marginLeft="90dp"
android:id="@+id/imageView"
android:layout_width="261dp"
android:layout_height="527dp"
app:srcCompat="@mipmap/title"
tools:layout_editor_absoluteX="141dp"
tools:layout_editor_absoluteY="132dp" />
</RelativeLayout>
MainActivity部分
package com.suk.rotate;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlertDialog;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RotateDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.suk.rotate.R;
public class MainActivity extends AppCompatActivity {
private ImageView fan;
private Button start;
private Button stop;
private Button accelerate;
private RotateAnimation rotate;
private Button decelerate;
private int duration=2000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fan = findViewById(R.id.fan);
start = findViewById(R.id.start);
stop = findViewById(R.id.stop);
accelerate = findViewById(R.id.accelerate);
decelerate = findViewById(R.id.decelerate);
}
@Override
protected void onStart() {
super.onStart();
rotate = new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotate.setInterpolator(new LinearInterpolator());
// rotate.setInterpolator(lin);
rotate.setDuration(2000);//设置动画持续周期
rotate.setRepeatCount(-1);//设置重复次数
// rotate.setFillAfter(true);//动画执行完后是否停留在执行完的状态
rotate.setStartOffset(10);//执行前的等待时间
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fan.startAnimation(rotate);
}
});
accelerate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (duration>10){
duration/=2;}
rotate.setDuration(duration);
fan.startAnimation(rotate);
}
});
decelerate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (duration<10000){
duration*=2;}
rotate.setDuration(duration);
fan.startAnimation(rotate);
}
});
/*
fan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("点我没用");
dialog.setIcon(R.drawable.fan);
dialog.setPositiveButton("OK",null);
dialog.setMessage("这是普通对话框");
View view=View.inflate(MainActivity.this,R.layout. activity_main1, null);
dialog.setView(view);
dialog.create();
dialog.show();
}
});
*/
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fan.clearAnimation();
}
});
}
}
需要有三个图片:
fan.png 风扇扇叶
border.png 风扇边框
title.png 贴图
(随便找一个能看就行)
来源:https://blog.csdn.net/w_Eternal/article/details/122296375


猜你喜欢
- 游戏服务器里面总是有一大堆的配置文件需要读取, 而且这些配置文件的读取: * 要不然做成弱类型的, 就是一堆字符串或者数字, 不能看出来错误
- 在Web开发过程中离不开数据的交互,这就需要规定交互数据的相关格式,以便数据在客户端与服务器之间进行传递。数据的格式通常有2种:1、xml;
- 在实际项目开发中,对于Excel的导入导出还是很常见的需求,比如说将数据根据模板批量导入到数据库中,以及将数据库中的数据批量导出陈Excel
- hibernate一级缓存和二级缓存的区别缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用
- 本文对c#中(int)、int.Parse()、int.TryParse、Convert.ToInt32的区别进行了较为深入的详细分析,对初
- 目录前言一、Spring Boot对Redis的支持二、实战1、添加依赖2、redis配置3、实现序列化4、创建Redis连接工厂,同时注册
- 需求:用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合;要按照总分从高到低进行排序分析:1.创建学生类 成员变
- cpu是时分(time division)的,操作系统里有很多线程,每个线程的运行时间由cpu决定,cpu会分给每个线程一个时间片,时间片是
- 如果你所在的公司的还没有使用swagger甚至没有听说过swagger,赶快学习一下我的这篇博客吧,五分钟速成,傻瓜式的集成,但就是这么简单
- 序言因为之前在项目中使用看groovy对业务进行一些抽象,效果比较好,过程中踩过一些坑,所以简单记录分享一下自己如何一步一步去实现的为什么用
- class文件中的attributes_count和attributesattributes_count位于class文件中methods的
- 本文实例讲述了java对象转型的概念,分享给大家供大家参考。具体方法如下:对象转型(casting)注意事项如下:1、一个基类的引用类型变量
- 在过去十年中最流行的移动应用开发开发平台中,我们认为,Android平台是一个新开发的最方便的平台。一个廉价的工具,友好的开发者社区,众所周
- 首先介绍一些乐观锁与悲观锁:悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个
- 对于很多开发人员来说,炫酷的UI效果是最吸引他们注意力的,很多人也因为这些炫酷的效果而去学习一些比较知名的UI库。而做出炫酷效果的前提是你必
- 在我们做项目的过程中,有可能会遇到跨域请求,所以需要我们自己组装支持跨域请求的JSONP数据,而在4.1版本以后的SpringMVC中,为我
- 后端实现1. 数据库设计我们需要设计两个表:用户表和角色表。用户表字段 类型 描述id bigint(20) 用户 IDusername v
- 照片墙这种功能现在应该算是挺常见了,在很多应用中你都可以经常看到照片墙的身影。它的设计思路其实也非常简单,用一个GridView控件当作“墙
- MyCat一个彻底开源的,面向企业应用开发的大数据库集群。基于阿里开源的Cobar产品而研发。能满足数据库数据大量存储;提高了查询性能。文章
- 初学Android编程,Android SDK中提供的Sample代码自然是最好的学习材料。