ConstraintLayout으로 아름다운 애니메이션하기

이 글은 Jinyan Cao가 작성한 Beautiful animations using Android ConstraintLayout 번역글입니다.

ConstraintLayout은 날이 갈 수록 인기를 더해가고 있습니다. 수평적인 뷰 계층 구조와 성능을 향상시키고, 임의의 경계 규칙을 지원합니다. 이전 레이아웃의 단점을 모두해결 할 것입니다. ConstraintLayout의 이점 중 하나는 매우 적은 코드로 멋진 애니메이션을 수행 할 수 있습니다. 이는 대부분의 개발자들이 알지못하며, 공식 문서에도 아무것도 언급되어 있지 않습니다.

방법?

ConstraintLayout의 기본 사항을 알고 있다고 가정합니다 (예: app:layout_constraintLeft_toLeftOf 및 다른 속성). 대부분의 문서또는 사이트에서는 새로 개선 된 Android Studio 레이아웃 디자인 패널을 사용하여 다양한 Constraint를 드래그/드롭/시각화 하는 방법만 소개되어 있습니다. 애니메이션의 목적을 위해서는 Constraint를 정확하게 이해하고 있어야만 조작이 가능합니다.

가장 간단한 형식인 TransitionManager(API 19 이상 또는 서포트 라이브러리에서 사용가능)를 통해 두 가지 Constraint 집합간에 애니메이션을 적용 할 수 있습니다. 긴 설명 보다 간단한 예제를 살펴 보겠습니다.

예제

Activity 실행시 초기화되는 XML 레이아웃부터 살펴 보겠습니다.

이것은 화면의 너비와 일치하는 화면 상단에 ImageView를 정의하는 기본 XML 파일입니다. (ConstraintLayout은 match_parent를 지원하지 않습니다.) 이제 하나의 추가 Constraint를 가진 대체 XML 레이아웃을 정의합시다.

여기서 유일한 차이점은 새 XML 레이아웃이 부모의 높이와 일치하는 높이로 설정하는것 입니다. 결과적으로 ImageView는 수직으로 가운데 정렬됩니다.
이제 두 개의 서로 다른 제약 조건 세트 (하나는 ImageView를 수직으로 중심에 배치하지 않고, 하나는 수직으로 가운데 배치)간에 애니메이션을 적용하려면 다음 코드를 Activity에 추가해야합니다.
(참고: 여기서는 Kotlin에 쓰여 있습니다. Kotlin에 익숙하지 않은 분은 Java 코드와 완전히 역 호환되는 동시에 최신 프로그래밍 언어의 많은 이점을 제공하므로 지금 시작하는 것이 좋습니다. 이제 Android에서 공식적으로 지원되는 언어입니다!)

constraintSet1과 constraintSet2는 비 수직 가운데 정렬과 수직 가운데 정렬에 대응하도록 설정합니다. 먼저 TransitionManager에 ConstraintLayout에서 지연된 전환을 시작하라고 지시합니다. 그런 다음 ConstraintLayout에 다른 Constraint 집합을 적용합니다. TransitionManager는 자동으로 애니메이션을 수행하여 Constraint의 변경 사항을 표시합니다.

실제로 XML 레이아웃을 복제하나요?

무엇을 생각하는지 알고 있습니다. 이 접근법은 Constraint 변경을 위해 레이아웃 파일을 복제해야합니다. 아무도 중복 된 코드를 좋아하지 않습니다.
이것은 실제로 생각만큼 나쁘지 않습니다. 전환을 위해 대체 XML파일 생성하는 경우 레이아웃의 모든 속성(예 : textSize)을 생략 할 수 있습니다. ConstraintSet은 각 뷰의 Constraint의 속성을 제외한 나머지 속성을 무시합니다. 이렇게하면 두 파일에서 일관된 스타일을 유지할 필요가 없습니다.(예: 원래 XML에서 textSize를 변경하면 대체 XML에서 이를 변경할 필요는 없습니다.)
XML 코드 복제를 하고 싶지 않는 경우, 코드에서 동적으로 속성을 변경하면 됩니다.
위의 예를 하나의 레이아웃 XML로 어떻게 변경하는지 살펴 보겠습니다.

위의 코드에서 constraintSet2에 속성을 코드에서 변경하여 애니메이션을 수행하고 있습니다. 이렇게하면 우리는 Constraint 속성을 그대로 유지하고 코드 복제를 피할 수 있습니다.

하지만 이미 Transition 프레임워크를 사용하여 동일하게 사용할 수 있다!
이것은 전혀 새로운 방식이 아닙니다. Transition 프레임워크 또는 animateLayoutChanges와 같은 속성을 사용하여 동일한 작업을 수행 할 수 있습니다. 그러나 Constraint를 지정할 수 있기때문에 훤씬 강력합니다.
또 다른 이 점은 많은 요소를 애니메이션으로 만들려고 할 때입니다. 이 애니메이션을 살펴 보겠습니다.

Robinhood가 ConstraintLayout을 사용하여 주문 애니메이션을 만듭니다.
Robinhood (Android)의 주문 흐름 애니메이션입니다. 페이지의 모든 단일 요소(카드, 사용자 정의 키패드, FAB 등)를 수동으로 애니메이팅 하도록 구현되어 있습니다. 이 코드는 특히 앞뒤 애니메이션을 따로 작업한다는 점을 감안할 때 읽기에 약간의 문제가 있습니다.
대신이 애니메이션에 ConstraintLayout을 사용하는 샘플 앱을 만들었습니다. 이 구현은 훨씬 간단합니다. 변경되어야 할 속성만 바꾼다음 대체 XML 레이아웃 파일을 지정하면 애니메이션 프레임워크가 모든 것을 애니메이션으로 변환합니다. UI에서 이 애니메이션을 처리하는 코드는 ~250라인에서 ~30라인으로 간단해졌습니다.

 

추가 팁!

ConstraintLayout 애니메이션을 시작하는 데 사용하는 코드를 기억하십니까?

두번째 파라미터를 이용하여 애니메이션을 커스터마이징 할 수있습니다!(기본은 내부에 구현된 기본 Transition 사용) 예를들어 애니메이션 속도를 쉽게 변경할 수 있습니다.

사소한주의 사항

ConstraintLayout 애니메이션으로 사용해본 후, 나는 애니메이션을 구현할 때 고려해야 할 몇 가지주의 사항을 발견했습니다.

  1. ConstraintLayout은 핸들링하는 자식에 대한 속성변경을 알고 있기때문에 직접 자식에 대해서만 애니메이션을 수행합니다. 이는 중첩 된 ViewGroups인 경우 잘 처리 되지 않음을 의미합니다. 위의 예제에서 CardView 내부의 텍스트는 외부 ConstraintLayout에 의해 처리되지 않으므로 코드에서 수동으로 애니메이션을 적용해야합니다. 이것은 아마도 중첩 된 ConstraintLayout을 사용하여 해결할 수 있지만 여기서는 사용하지 않았습니다.

  2. ConstraintLayout은 레이아웃 관련 변경 사항 만 애니메이션으로 나타냅니다. 대체 XML에서 다른 속성(예: elevation, text)을 읽을 수 없으며 프레임워크가 모든 것을 처리 합니다. ConstraintSet.clone()은 레이아웃/Constraint 변경 사항을 복사하고 다른 모든 항목은 삭제합니다.

  3. constraint-layout:1.0.2에서 ConstraintLayout 속성을 동적으로 변경하면 업데이트 된 속성을 고려하지 않고 애니메이션됩니다.(예: translationY). 즉, 애니메이션을 실행하면 변경전의 속성의 값으로 되돌아 간뒤 새로운 값으로 애니메이션이 적용됩니다.

마치며..

ConstraintLayout을 사용하는 페이지에서 애니메이션을 구현할 함으로 Transition 프레임 워크 보다 많은 기본 레이아웃 변경 애니메이션을 수행 할 수 있습니다. 이를 통해 Activity/Fragment에서 UI/애니메이션 로직을 압축하고 XML로 통합 할 수 있습니다. 또한 더 읽기 쉬운 애니메이션 구조를 만듭니다. (아무도 코드로 작성된 방식의 애니메이션을 읽는 것을 좋아하지 않습니다).

구글 I/O 2017, Android 새로운 기능 정리

구글 I/O 2017 안드로이드 키노트 정리를 해보겠습니다. 안드로이드 O부분도 있지만, 지금 바로 사용가능한 서포트 라이브러리에 대한 소식도 많습니다.

2017-05-18 오전 10.52.39

16비트 PNG파일을 지원합니다. 새로운 유틸 클래스를 이용하면 16비트의 PNG파일을 사용 할 수 있습니다.

2017-05-18 오전 10.53.15
24비트 vs 16비트

핵심적인 컬러값만을 사용하여, 복잡하지 않은 이미지에 사용한다면 용량과 성능을 높일 수 있습니다.

2017-05-18 오전 10.53.38

멀티 윈도우를 지원하는 앱이라면, 멀티 디스플레이도 지원할 수 있습니다. 앱이 실행될때 사용자는 임의로 제어가능하며, 앱에서도 ActivityOptions를 통해 제어할 수 있습니다.

2017-05-18 오전 10.54.08

멀티 디스플레이 테스트는 adb shell 명령을 통해 멀티 디스플레이를 사용할 액티비티를 실행 할 수 있습니다.

2017-05-18 오전 10.54.51

미디어 매트릭스 API를 지원합니다. 이를 통해 미디어에 대한 정보(해상도, 프레임등)를 간단하게 얻어 올 수 있습니다.

2017-05-18 오전 10.55.11

MediaPlayer에서 버퍼링을 제어 할 수 있도록 개선되었습니다. 또한 훨신 쉽게 DRM Playback을 지원합니다.

2017-05-18 오전 10.56.08

MPEG-2 TS 포맷 지원도 합니다.

2017-05-18 오전 10.56.23

크롬 브라우저에서 지원하는 안전하지 않는 웹 페이지의 기능을 웹뷰에서도 사용가능합니다. 안드로이드 매니페스트에 메타 태그를 간단히 추가만하면 됩니다. 또한 멀티 프로세스를 위한 새로운 API도 추가되었습니다.

2017-05-18 오전 10.57.49

setCurrentPlayTime()을 통해 애니메이션할 시간을 임의로 지정 가능합니다. 이는 자유자재로 애니메이션 플레이를 제어 할 수 있습니다. 또한 reverse()를 통해 반대로 애니메이션 할수 있도록 지원합니다.

2017-05-18 오전 10.58.31

사용자 정보를 자동으로 채울 수 있는 자동완성 기능도 추가 되었습니다.

2017-05-18 오전 11.00.23

글꼴 리소스를 공식 지원합니다.

2017-05-18 오전 11.00.52

글꼴을 앱에 탑제하지 않고 구글 플레이 서비스의 폰트 프로바이더를 통해서도 사용가능합니다.

2017-05-18 오전 11.01.39

텍스트뷰의 텍스트를 자동으로 사이즈 변경기능을 지원합니다. 텍스트의 크기를 자동으로 뷰 사이즈 크기에 맞게끔 변경해줍니다. 이 모든것은 서포트 라이브러리를 통해 사용가능합니다.

2017-05-18 오전 11.02.55

접근성 서비스의 경우 언어 감지, 볼륨 컨트롤 사용자 정의, 제스쳐 사용자 정의를 지원합니다.

2017-05-18 오전 11.03.41

findViewById는 이제 자동 캐스팅을 지원합니다. 하지만 이를 대처할만한 라이브러리가 많고 하위 안드로이드 O에서만 지원하기 때문에 그렇게 유용하지는 않을듯 합니다.

2017-05-18 오전 11.04.51

반응형 아이콘을 만들수 있습니다. 아이콘은 배경과 전경으로 이루어지며, 런처는 마스크를 통해 아이콘 모양을 직접 디자인 할 수 있습니다.

2017-05-18 오전 11.06.00

바로 가기또는 위젯 생성을 위한 새로운 Action이 추가 되었습니다. 런처의 위젯 추가가 아닌 앱에서 바로 위젯을 추가 요청을 할 수 있습니다.

2017-05-18 오전 11.06.14

ShortCutManager, AppWidgetManager를 통해 바로가기, 위젯 추가 요청을 하면 Manager의 다이얼로그가 나타납니다. 이를 통해 위젯의 사용성을 향상 할 수 있습니다.

2017-05-18 오전 11.06.55

수 많은 알림은 사용자가 원하는 정보를 얻기에는 매우 어렵습니다. 또한 사용자가 임의로 제어기도 힘듭니다.

2017-05-18 오전 11.07.22

이런 문제점으로 안드로이드 젤리빈에서는 알림을 블락처리하는 기능을 추가 했었으며, 안드로이드 누가에서는 무음으로 처리하는 기능이 추가 되었습니다.

2017-05-18 오전 11.07.43

하지만 여기에도 앱내에서 기능별로 알림을 제어 할 수 없다는 문제점이 있습니다. 안드로이드 O에서는 동일한 동작을 하는 알림을 채널별로 나누어 사용자가 컨트롤 할 수 있는 기능을 추가 하였습니다.

2017-05-18 오전 11.10.13

Strict Mode에 Unbuffer I/O와 sockets, URI를 감시하는 기능이 추가 되었습니다.

2017-05-18 오전 11.14.52

구글 플레이는 설치된 모든 앱에 대해 검증된 앱인지를 판별 해주는 “구글 플레이 프로텍트”기능이 추가 되었습니다. 플레이 스토어뿐만 아니라 직접설치, 다른 스토어에서 설치된 앱도 잠재적인 위험이 있는지에 대해 스캐닝 해줍니다.

2017-05-18 오전 11.20.35

새로운 복사 수집기능이 추가 되었으며, 최적화된 힙 관리기술도 추가 되었습니다.

2017-05-18 오전 11.23.28

물리학 기반의 애니메이션 시스템을 통해 개발자는 복잡한 수학 계산필요 없이 단순히 자연어를 통해 물리학 기반의 애니메이션을 구현 할 수 있습니다.

이 외에도 Activity 라이프사이클을 좀 더 단순화하였으며, 배터리 최적화를 위해 백그라운드 처리에 대한 좀 더 타이트한 기술등 소개되었습니다.