简书链接:android花了点时间研究三种方法实现旋转动画
文章字数:991,阅读全文大约需要3分钟
这里不介绍自定义的了,我之前用的是spinkit的动画,360加固后各种无响应,搞得我恐惧了,

第一种

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class ProgressBar extends androidx.appcompat.widget.AppCompatImageView {
/* public ProgressBar(Context context, Style style, int color) {
super(context, null, color);
initAnimator();
}*/

public ProgressBar(Context context) {

super(context);
initAnimator(context);
}

public ProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
initAnimator(context);
}

public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAnimator(context);
}

private void initAnimator(Context context) {
// setImageResource(R.drawable.loading_progress);

// 开始播放动画


/* ColorStateList colorStateList = new ColorStateList(new int[][]{{android.R.attr.state_pressed, android.R.attr.state_enabled}, {android.R.attr.state_pressed}}, new int[]{Color.RED, Color.BLUE});
setImageTintList(colorStateList);*/
// setImageTintList(ColorStateList.valueOf(AppUtils.attrFetchAttrValue(getContext(), R.attr.defaultThemeColor)));

Drawable up = ContextCompat.getDrawable(context, R.drawable.icon_loading_progress);
Drawable drawableUp = DrawableCompat.wrap(up);
DrawableCompat.setTint(drawableUp, AppUtils.attrFetchColor(context, R.attr.defaultThemeColor));
this.setImageDrawable(drawableUp);

// 设置动画播放的时间
AnimationSet animationSet = new AnimationSet(true);
//参数1:从哪个旋转角度开始
//参数2:转到什么角度
//后4个参数用于设置围绕着旋转的圆的圆心在哪里
//参数3:确定x轴坐标的类型,有ABSOLUT绝对坐标、RELATIVE_TO_SELF相对于自身坐标、RELATIVE_TO_PARENT相对于父控件的坐标
//参数4:x轴的值,0.5f表明是以自身这个控件的一半长度为x轴
//参数5:确定y轴坐标的类型
//参数6:y轴的值,0.5f表明是以自身这个控件的一半长度为x轴
RotateAnimation rotateAnimation = new RotateAnimation(0, 360*4,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimation.setDuration(6000);
rotateAnimation.setRepeatMode(Animation.INFINITE);
rotateAnimation.setRepeatCount(Animation.INFINITE);
animationSet.addAnimation(rotateAnimation);
animationSet.setRepeatMode(Animation.INFINITE);
animationSet.setRepeatCount(Animation.INFINITE);
this.startAnimation(animationSet);
}

@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}

@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
}

@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
}

设置setRepeatMode 得设置在子动画否则无法重复

第二种

java基于progressbar设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class ProgressBar1 extends ProgressBar {

public ProgressBar1(Context context) {

super(context);
init(context);
}

public ProgressBar1(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}

public ProgressBar1(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}

public ProgressBar1(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}

private void init(Context context) {
RotateDrawable rotateDrawable = new RotateDrawable();
Drawable drawable = ContextCompat.getDrawable(context, R.drawable.drawable_progerss1);
drawable.setTint(AppUtils.attrFetchColor(context, R.attr.defaultThemeColor));
rotateDrawable.setDrawable(drawable);
rotateDrawable.setPivotX(0.5f);
rotateDrawable.setPivotXRelative(true);
rotateDrawable.setPivotYRelative(true);
rotateDrawable.setPivotY(0.5f);
rotateDrawable.setFromDegrees(0);
rotateDrawable.setToDegrees(360);
setIndeterminateDrawable(drawable);
/*setind
//setInd
android:indeterminateDuration="2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminateBehavior="repeat"*/
}

@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
}

@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
}

需要借助drawalbe/xml drawable_progerss1

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate android:drawable="@drawable/icon_loading_progress"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="5000"
xmlns:android="http://schemas.android.com/apk/res/android"></animated-rotate>

第三种也是如此,第二种由于无法代码修改(除非反射) 速度,第二种通常只能通过设置大角度来加速了

第三种

自带 drawable_progress或者drawable_progress1一样的

1
2
3
4
5
6
7
<ProgressBar
android:layout_width="50dp"
android:layout_height="50dp"
android:indeterminateBehavior="repeat"
android:indeterminateDrawable="@drawable/drawable_progress"
android:indeterminateDuration="3000" />

drawable_progress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360">
<shape
android:innerRadius="8dp"
android:shape="ring"
android:thickness="3dp"
android:useLevel="false">
<gradient
android:centerY="0.50"
android:endColor="#cccccc"
android:startColor="?attr/defaultThemeColor"
android:type="sweep"
android:useLevel="false" />
</shape>

<!-- android:pivotX 动画执行的起点x坐标 50%代表相对自身宽度的
android:innerRadius 内环的半径
android:thickness 环的厚度
android:useLevel 只有当我们的shape使用在LevelListDrawable中时,这个值为true,否则为false
android:centerY 渐变中心Y的相对位置,值为0-1
android:type 渐变类型,还有linear,radial两种类型,线性渐变和放射渐变-->

</animated-rotate>

文章中的图片资源 icon_loading_progress

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="210.4dp"
android:height="200dp"
android:viewportWidth="1077"
android:viewportHeight="1024">
<path
android:pathData="M89.8,178.1a149.7,148.4 0,1 0,299.4 0,149.7 148.4,0 1,0 -299.4,0Z"
android:fillColor="#E44232"/>
<path
android:pathData="M0,504.6a119.8,118.7 0,1 0,239.5 0,119.8 118.7,0 1,0 -239.5,0Z"
android:fillColor="#E44232"
android:fillAlpha="0.9"/>
<path
android:pathData="M104.8,794a112.3,111.3 0,1 0,224.6 0,112.3 111.3,0 1,0 -224.6,0Z"
android:fillColor="#E44232"
android:fillAlpha="0.8"/>
<path
android:pathData="M434.2,920.1a104.8,103.9 0,1 0,209.6 0,104.8 103.9,0 1,0 -209.6,0Z"
android:fillColor="#E44232"
android:fillAlpha="0.7"/>
<path
android:pathData="M763.5,808.8a97.3,96.5 0,1 0,194.6 0,97.3 96.5,0 1,0 -194.6,0Z"
android:fillColor="#E44232"
android:fillAlpha="0.6"/>
<path
android:pathData="M913.2,482.3a82.3,81.6 0,1 0,164.7 0,82.3 81.6,0 1,0 -164.7,0Z"
android:fillColor="#E44232"
android:fillAlpha="0.5"/>
<path
android:pathData="M808.4,185.5a67.4,66.8 0,1 0,134.7 0,67.4 66.8,0 1,0 -134.7,0Z"
android:fillColor="#E44232"
android:fillAlpha="0.4"/>
<path
android:pathData="M524,51.9a52.4,51.9 0,1 0,104.8 0,52.4 51.9,0 1,0 -104.8,0Z"
android:fillColor="#E44232"
android:fillAlpha="0.3"/>
</vector>

image.png