[Android / Kotlin] MotionLayout을 사용하여 Splash 만들기

Subeen·2024년 2월 17일
0

Android

목록 보기
60/73

결과 화면

activity_splash.xml

xml의 Design Editor에서 ConstraintLayout > Convert to MotionLayout > CONVERT를 하면 res/xml/ 위치에 activity_splash_scene 파일이 생성된다.
scene은 모든 애니메이션 관련 내용이 들어갈 MotionScene 을 정의한 파일이다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/motionLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    app:layoutDescription="@xml/activity_splash_scene">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/backgroundLayout"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:background="@drawable/bg"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/blueLogo"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/ic_logo_splash"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/whiteLogo"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/ic_logo_splash"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:tint="@color/white" />

</androidx.constraintlayout.motion.widget.MotionLayout>

bg.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#3D70ED" />
    <corners android:radius="500dp" />
</shape>

activity_splash_scene.xml

MotionScene 안에 Transition를 정의하고, 애니메이션의 시작과 끝의 View의 위치를 정의해놓은 파일인 motion:constraintSetStart와 motion:constraintSetEnd을 설정해준다.

  • autoTransition="animateToEnd" : 자동으로 종료 상태로 전환한다.
  • duration="1000" : 전환 시간을 1초로 설정한다.
  • 시작 상태(@+id/start)
    • backgroundLayout : 시작 시에는 확대 된 상태이다.
    • blueLogo : 시작 시에는 투명하고 축소되어 중앙에 배치된다.
    • whiteLogo : 시작 시에는 일반적인 크기로 설정한다.
  • 종료 상태(@+id/end)
    • backgroundLayout : 종료 시에는 아무것도 없는 상태로 축소 된다.
    • blueLogo : 종료 시에는 cubic Easing을 사용하여 페이드 인, 확대 및 전환 한다.
    • whiteLogo : 종료 시에는 축소 되어 사라진다.
  • motion:constraintSetStart : 시작 ConstraintSet 또는 Constraint 값들을 가져올 layout xml 파일을 설정한다.
  • motion:constraintSetEnd : 종료 ConstraintSet 또는 Constraint 값들을 가져올 layout xml 파일을 설정한다.
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:motion="http://schemas.android.com/apk/res-auto">

    <Transition
        motion:autoTransition="animateToEnd"
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="1000">
        <KeyFrameSet></KeyFrameSet>
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/backgroundLayout"
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:scaleX="10"
            android:scaleY="10"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/blueLogo"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:alpha="0"
            android:scaleX="0"
            android:scaleY="0"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/whiteLogo"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:scaleX="1"
            android:scaleY="1"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/backgroundLayout"
            android:layout_width="150dp"
            android:layout_height="150dp"
            android:scaleX="0"
            android:scaleY="0"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
        <Constraint
            android:id="@+id/blueLogo"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:alpha="1"
            android:scaleX="1"
            android:scaleY="1"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent"
            motion:transitionEasing="cubic(1,0,1,0)" />
        <Constraint
            android:id="@+id/whiteLogo"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:scaleX="0"
            android:scaleY="0"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />
    </ConstraintSet>
</MotionScene>

SplashActivity.kt

class SplashActivity : AppCompatActivity() {
    private val SPLASH_TIME_OUT: Long = 3000

    private val binding: ActivitySplashBinding by lazy {
        ActivitySplashBinding.inflate(layoutInflater)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)

		// Spash가 시작되고 3초 뒤에 MainActivity로 전환한다. 
        Handler(Looper.getMainLooper()).postDelayed({
            val intent = Intent(this@SplashActivity, MainActivity::class.java)
            startActivity(intent)
            finish()
        }, SPLASH_TIME_OUT)
    }
}
profile
개발 공부 기록 🌱

0개의 댓글