Header
关于SVG,可以看下这个。
另外一篇关于SVG的文章
看下效果吧
Body
直接上代码得了,关于SVG的东西,开头都有链接的。
1.画所需图形
blue_circle.xml
<path
android:name="circle_bg"
android:strokeColor="#dddddd"
android:strokeWidth="1"
android:strokeLineCap="square"
android:pathData="M 15,2
A 13,13 0 1,1 14.9,2"/>
<group
android:name="circlegroup"
android:pivotY="15"
android:pivotX="15">
<path
android:name="circle"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="square"
android:pathData="M 15,2
A 13,13 0 1,1 14.9,2"
android:trimPathEnd="1"/>
</group>
<path
android:name="hook"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="butt"
android:pathData="M 8,15
L 14,20
L 23,11"
android:trimPathEnd="1"/>
<path
android:name="x1"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="butt"
android:pathData="M 8,8
L 22,22"
android:trimPathEnd="1"/>
<path
android:name="x2"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="butt"
android:pathData="M 22,8
L 8,22"
android:trimPathEnd="1"/>
整体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="30dp"
android:height="30dp"
android:viewportWidth="30.0"
android:viewportHeight="30.0">
<path
android:name="circle_bg"
android:strokeColor="#dddddd"
android:strokeWidth="1"
android:strokeLineCap="square"
android:trimPathEnd="1"
android:pathData="M 15,2
A 13,13 0 1,1 14.9,2"/>
<group
android:name="circlegroup"
android:pivotY="15"
android:pivotX="15">
<path
android:name="circle"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="square"
android:pathData="M 15,2
A 13,13 0 1,1 14.9,2"
android:trimPathEnd="0"/>
</group>
<path
android:name="hook"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="butt"
android:pathData="M 8,15
L 14,20
L 23,11"
android:trimPathEnd="0"/>
<path
android:name="x1"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="butt"
android:pathData="M 8,8
L 22,22"
android:trimPathEnd="0"/>
<path
android:name="x2"
android:strokeColor="#6633ff"
android:strokeWidth="1"
android:strokeLineCap="butt"
android:pathData="M 22,8
L 8,22"
android:trimPathEnd="0"/>
</vector>
2.设置所需要的动画(animator)
animator_blue_circle_totation.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="rotation"
android:valueType="floatType"
android:valueFrom="0"
android:valueTo="360"
android:duration="2000"
android:repeatMode="restart"
android:repeatCount="infinite"
android:interpolator="@android:anim/decelerate_interpolator">
</objectAnimator>
animator_blue_circle_trimpathend.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:interpolator="@android:interpolator/linear"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType">
</objectAnimator>
animator_blue_circle_trimpathend_is_one.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="10"
android:interpolator="@android:interpolator/linear"
android:propertyName="trimPathEnd"
android:valueFrom="1"
android:valueTo="1"
android:valueType="floatType">
</objectAnimator>
animator_blue_circle_loading_set.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:duration="2000"
android:interpolator="@android:anim/decelerate_interpolator"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1"
android:repeatMode="restart"
android:repeatCount="infinite"
android:valueType="floatType"/>
<objectAnimator
android:duration="2000"
android:interpolator="@android:anim/accelerate_interpolator"
android:propertyName="trimPathStart"
android:valueFrom="0"
android:valueTo="1"
android:repeatMode="restart"
android:repeatCount="infinite"
android:valueType="floatType"/>
</set>
3.将动画和矢量图形联系起来
animated_vector_blue_circle_loading.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:drawable="@drawable/blue_circle"
tools:ignore="NewApi">
<target
android:animation="@animator/animator_blue_circle_loading_set"
android:name="circle"/>
<target
android:animation="@animator/animator_blue_circle_rotation"
android:name="circlegroup"/>
</animated-vector>
animated_vector_blue_circle_success.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="NewApi"
android:drawable="@drawable/blue_circle">
<target
android:animation="@animator/animator_blue_circle_trimpathend"
android:name="hook"/>
<target
android:animation="@animator/animator_blue_circle_trimpathend_is_one"
android:name="circle"/>
</animated-vector>
animated_vector_blue_circle_failed.xml
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
tools:ignore="NewApi"
android:drawable="@drawable/blue_circle">
<target
android:animation="@animator/animator_blue_circle_trimpathend"
android:name="x1"/>
<target
android:animation="@animator/animator_blue_circle_trimpathend"
android:name="x2"/>
<target
android:animation="@animator/animator_blue_circle_trimpathend_is_one"
android:name="circle"/>
</animated-vector>
准备工作完成,把矢量图形放到控件中去控制
public class CircleLoadingView extends AppCompatImageView {
//当前状态
private enum state{
LOADING,
SUCCESS,
FAILED
}
private state currentState = state.LOADING;
public CircleLoadingView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
//初始化
private void initView(){
setImageResource(R.drawable.animated_vector_blue_circle_loading);
AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable();
drawable.start();
}
//开始加载
final public void startLoading(){
if (currentState == state.LOADING){
return;
}
setImageResource(R.drawable.animated_vector_blue_circle_loading);
AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable();
drawable.start();
currentState = state.LOADING;
}
//加载成功
final public void success(){
if (currentState == state.SUCCESS){
return;
}
setImageResource(R.drawable.animated_vector_blue_circle_success);
AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable();
drawable.start();
currentState = state.SUCCESS;
}
//加载失败
final public void fail(){
if (currentState == state.FAILED){
return;
}
setImageResource(R.drawable.animated_vector_blue_circle_failed);
AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable();
drawable.start();
currentState = state.FAILED;
}
final public state getCurrentState(){
return currentState;
}
}
完成,测试一下
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="20dp">
<TextView
android:id="@+id/play"
android:layout_width="90dp"
android:layout_height="90dp"
android:background="#999999"
android:text="success"
android:gravity="center"
android:layout_marginRight="20dp"/>
<TextView
android:id="@+id/pause"
android:layout_width="90dp"
android:layout_height="90dp"
android:text="failed"
android:gravity="center"
android:background="#999999"/>
</LinearLayout>
<com.will.circleloadingview.CircleLoadingView
android:id="@+id/loadingview"
android:layout_width="100dp"
android:layout_height="100dp" />
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private CircleLoadingView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = findViewById(R.id.loadingview);
TextView play = findViewById(R.id.play);
TextView pause = findViewById(R.id.pause);
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.success();
}
});
pause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.fail();
}
});
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
view.startLoading();
}
});
}
}
完成,就和Header的效果一样
End
还有更多更复杂的SVG的东西,后面会再研究。
Demo地址:https://github.com/ApeForProgram/SVGCircleLoadingView/tree/master