어떤 xml로 표현되는 리소스는 내부에 다른 여러 리소스를 포함할 수 있다. 아래 res/drawable/avd.xml 는 3개의 xml 리소스 파일을 포함한다.
내부 리소스 파일들을 재사용하기 위한 <res/drawable/avd.xml>
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vectordrawable" >
<target
android:name="rotationGroup"
android:animation="@animator/rotation" />
</animated-vector>
<vectordrawable 리소스에 rotation 리소스 애니메이션을 적용한 avd.xml 리소스>
<res/drawable/vectordrawable.xml>
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="64dp"
android:width="64dp"
android:viewportHeight="600"
android:viewportWidth="600" >
<group
android:name="rotationGroup"
android:pivotX="300.0"
android:pivotY="300.0"
android:rotation="45.0" >
<path
android:fillColor="#000000"
android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
</group>
</vector>
<검정색 삼각형을 그리는 벡터 리소스>
위 소스를 통해 아래와 같은 리소스를 그릴 수 있습니다.
<res/drawable/vectordrawable.xml>
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="6000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:repeatMode="restart"
android:repeatCount="infinite"/>
<6초 동안 0도에서 360도까지 무한 회전하는 리소스>
위 처럼 리소스를 여러 파일로 분류하여 생성하고 관리하면 vectordrawable.xml, rotation.xml 파일의 재사용성이 좋아진다.
만약 vectordrawable.xml과 rotation.xml 각각 리소스들이 avd.xml 밖에서 쓰이지 않는다면 아래처럼 간단하게 구현할 수 있다.
내부 리소스들의 재사용 가능성이 없는 경우의 <res/drawable/avd.xml>
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt" >
<aapt:attr name="android:drawable" >
<vector
android:height="64dp"
android:width="64dp"
android:viewportHeight="600"
android:viewportWidth="600" >
<group
android:name="rotationGroup"
android:pivotX="300.0"
android:pivotY="300.0"
android:rotation="45.0" >
<path
android:fillColor="#000000"
android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
</group>
</vector>
</aapt:attr>
<target android:name="rotationGroup">
<aapt:attr name="android:animation" >
<objectAnimator
android:duration="6000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:repeatMode="restart"
android:repeatCount="infinite"/>
</aapt:attr>
</target>
</animated-vector>
위와 같이 <aapt:attr > 태그를 사용하면 aapt 태그 안의 소스들이 리소스로 인식되며 자체 리소스 파일로 생성된다. aapt의 name 값은 상위 태그 내에서 리소스를 사용할 속성의 이름을 선언할 수 있습니다.
가장 위에 나온 res/drawable/avd.xml와 가장 아래에 나온 소스에서 aapt가 어떤 속성으로 대체되는지 생각하면 이해가 쉽습니다.
위 소스에 대한 결과는 아래 activity_main.xml과 MainActivity.java를 적용하여 확인할 수 있습니다. 전체 프로젝트는 아래 깃헙 링크에서 확인할 수 있습니다.
https://github.com/yebonkim/Android-Animation-Practice
<참고> activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<참고> MainActivity.java
package com.yebon.playground;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.os.Bundle;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private ImageView image;
private AnimatedVectorDrawable vector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
vector = (AnimatedVectorDrawable) ContextCompat.getDrawable(this, R.drawable.avd);
image = findViewById(R.id.image);
image.setImageDrawable(vector);
vector.start();
}
}
댓글 영역