안드로이드

[Android/Kotlin] MotionLayout - 2 ( 실제로 적용해보자.)

mingmaeng 2020. 9. 17. 21:32

지난 포스팅에서 다룬 MotionLayout의 개념을 바탕으로 실제로 실습한 내용에 대해 포스팅하겠습니다.

지난 글을 못 읽으셨던 분은 아래 링크를 타고 한 번 읽고 오신다면 이해하기 편하실 겁니다.

kangmin1012.tistory.com/41

 

[Android/Kotlin] MotionLayout (애니메이션을 쉽게 적용하기)

안드로이드 앱을 만들 때마다 항상 하는 고민이 있습니다. 어떻게 해야 앱을 멋있게 만들 수 있을까.... UI/UX에 맞게 앱을 만드는 것도 멋있지만 거기에 애니메이션이 추가가 된다면 얼마나 멋있�

kangmin1012.tistory.com

 


지난 글에 저는 Android Studio가 4.0으로 올라오면서 MotionLayout Editor를 지원한다고 얘기했었습니다.

그래서 이번에 해당 기능을 이용해 쉽게 MotionLayout을 적용하는 실습을 진행하였고, 글을 작성하도록 하겠습니다.

 

 

처음 실습은 한 유튜브를 참고하여 트위터 로고를 이용한 스플래시 화면을 클론 코딩해보겠습니다.

출처 : youtu.be/kcTK3Ex6Ve4

 

1. XML작성은 동일하다!

먼저 xml을 작성하겠습니다. xml 작성은 별다른 어려움 없이 ConstraintLayout으로 작성해주시면 됩니다.

 

트위터 로고는 Twitter 홈페이지에서 받은 다음 사용하시면 됩니다.

한가운데에 로고를 넣고 나머지 배경을 트위터의 파란색으로 채워줍니다.

 

<?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"
    android:background="@color/mainBlue">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="160dp"
        android:layout_height="160dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_twitter_logo_whiteonblue" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

2. ConstraintLayout 2.0부터 기본 장착된 MotionLayout

기본적인 뷰 세팅이 완료되었다면 이제 MotionLayout 태그로 바꿔주면 됩니다.

현재 ConstraintLayout2.0 버전이 기본적으로 MotionLayout을 탑재하고 있습니다. 예전에는 gradle에 추가를 해줘야 했는데, 지금은 그럴 필요가 없죠.

 

최상단 레이아웃을 우클릭 -> 'Convert to MotionLayout'을 클릭하시면 MotionLayout으로 바꿔줄뿐더러

알아서 MotionScene까지 만들어 줍니다.

 

Convert to MotionLayout 클릭

 

적용 후 화면. 좌측 하단에 있는 ConstraintSet은 없는게 정상입니다.(이미 실습해서 사진엔 있습니다.)

해당 화면이 MotionLayout Editor입니다. MotionScene에서 직접적인 코드 작성을 통해 애니메이션을 구현해도 되지만,

좀 더 쉽게 다가가기 위해서 + 새로 생긴 기능을 써보는 의미로 MotionLayout Editor를 사용하겠습니다.

 

3. 영상 편집하듯이 애니메이션 적용

MotionLayout Editor의 장점은 GUI로 애니메이션을 쉽게 적용할 수 있다는 점입니다.

Google에서 새롭게 지원해준 기능인만큼 저희는 그 기능을 사용해주는 것이 도리겠죠? 바로 사용해 봅시다.

 

유튜브와 동일하게 트위터 이미지가 줄어들었다가 순식간에 커지는 애니메이션을 만들어 보겠습니다.

MotionLayout Editor 위쪽에 start와 end 사이에 있는 화살표를 누르면 아래 화면이 마치 영상편집을 하듯이 타임라인으로 바뀌어 있게 됩니다.

 

빨간 원을 클릭하면 아래 타임라인이 생깁니다.

우리는 트위터 로고가 줄었다가 커지는 애니메이션. 즉, scale 애니메이션을 줄 것입니다.

30 부근에 타임라인 선을 놓고( framePosition = 30 ) 우측 타이머 아이콘을 누른 다음 KeyAttribute를 눌러줍니다.

 

KeyAttribute를 클릭 후 Attribute 속성을 scaleX로 두고 추가해 줍니다.

그러면 타임라인에 하나의 점이 찍히게 되는데 이 점을 클릭하면 우측에 속성들이 나오게 됩니다.

+ 버튼을 눌러서 scaleY도 추가해주고 두 속성 모두 0.7로 변경합니다.

 

빨간 동그라미에서 scaleY 추가 후 두 속성 모두 0.7로 설정

 

이렇게 되면 0 ~ 30 구간까지 로고가 0.7만큼 줄어들게 됩니다.

재생 버튼을 누르면 에뮬레이터 실행 없이 애니메이션을 확인할 수 있습니다.

 

이제 로고가 화면을 채울 만큼 커질 차례입니다. 라인을 맨 끝으로 두고 위와 같이 키프레임을 생성해줍니다.

scaleX와 scaleY를 30으로 설정해줍니다.

 

최종적으로 MotionScene코드를 살펴보면 다음과 같이 설정된 것을 볼 수 있습니다.

 

<?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:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@id/start"
        motion:duration="800">
       <KeyFrameSet>
           <KeyAttribute
               motion:motionTarget="@+id/imageView"
               motion:framePosition="30"
               android:scaleX="0.7"
               android:scaleY="0.7" />
           <KeyAttribute
               motion:motionTarget="@+id/imageView"
               motion:framePosition="100"
               android:scaleX="30"
               android:scaleY="30" />
       </KeyFrameSet>
        <OnClick motion:targetId="@+id/imageView"
            motion:clickAction="toggle"/>
    </Transition>

    <ConstraintSet android:id="@+id/start">
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
    </ConstraintSet>
</MotionScene>

 

<Transition> 태그의 duration 속성을 이용해서 전체 애니메이션 동작 시간을 조절할 수 있습니다.

저는 0.8초로 설정했습니다.

 

태그를 보시면 <OnClick> 태그가 있는 걸 볼 수 있습니다. 해당 태그는 터치 이벤트를 설정할 수 있는 태그입니다.

여러분들이 위에 내용을 따라오셨다면 아직 작성되어있지 않을 것입니다.

 

<OnClick>은 클릭했을 경우 애니메이션을 실행하게 됩니다. 직접 xml 코드를 작성해주셔도 되고, MotionEditor를 이용해 추가해주셔도 됩니다.

 

 

빨간 부분 클릭 -> Click Handler를 클릭한 다음 추가해주시면 MotionScene에 태그가 생성된 것을 볼 수 있습니다.

 

 <OnClick> 태그의 clickAction 속성을 'toggle'로 설정해주시면 start->end / end->start로 역방향 애니메이션도 작동합니다.

 

4. 클릭이벤트를 호출해 스플래시 화면처럼 만들어보자.

 

실습에서 만든 화면은 로고를 눌러야만 애니메이션이 동작합니다.

여기서 더 나아가서 스플래시 화면처럼 자동적으로 애니메이션이 실행되게 해 보겠습니다.

 

2초 뒤에 callOnClick() 함수를 호출하여 애니메이션을 실행되게 만들면 스플래시 화면처럼 자동으로 애니메이션이

동작하게 됩니다.

 

class MainActivity : AppCompatActivity() {
    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        val handler = Handler(mainLooper)

        handler.postDelayed(Runnable {
            run {
                imageView.callOnClick()
            }
        },2000)
        
        ...
   }
}

 

 

실행하게 되면 다음과 같은 화면이 나오게 됩니다.

 

 


이번 포스팅에서는 유튜브에 있는 MotionLayout 실습을 따라 해 보고 추가적으로 자동 호출까지 해봤습니다.

다른 실습으로는 로티 애니메이션과 뷰 페이저를 연동해서 다음 웹툰의 메인 화면 애니메이션을 연출해 보는 실습입니다.

해당 실습은 글이 길어져서 다음 포스팅에 하도록 하겠습니다.