본문 바로가기
개발/안드로이드

API 23의 -round 식별자로 Android Wear의 둥근 화면을 아름답게 만들어보세요

by darksilber 2016. 5. 17.
반응형

출처 - http://googledevkr.blogspot.kr/

 

API 23의 -round 식별자로 Android Wear의 둥근 화면을 아름답게 만들어보세요

 

작성자: Hoi Lam, 디벨로퍼 어드보케, Android Wear

Android Wear는 결국 선택의 문제입니다. 사용자들은 애초부터 둥근 화면의 시계 등, 자신이 원하는 스타일을 선택할 수 있었습니다. Android Wear API 23에서는 여러분이 근사한 코드가 뒷받침해주는 기분 좋은 코딩 경험을 누릴 수 있도록, 훨씬 더 나은 개발자 지원을 가능하도록 했습니다. 이 API 23의 핵심 구성 요소는 원형 기기와 사각형 기기 간에 레이아웃, 치수 등의 리소스 파일을 구분하는 데 도움이 되는 새 round 리소스 식별자입니다. 이 글에서는 개발자들에게 어떤 옵션이 주어지는지, 그리고 왜 dimens.xml을 중요하게 여겨야 하는지 설명드리겠습니다. 그 밖에, 턱이 있는 기기를 다루는 최상의 방법에 대해서도 간략히 소개하겠습니다.

시작할 준비가 되셨나요? BoxInsetLayout을 고려해 보세요!

콘텐츠가 하나의 사각형 화면에 모두 들어맞을 수 있다면 BoxInsetLayout을 사용하세요. 이 클래스는 처음부터 Wearable 지원 라이브러리에 포함되었는데, 모든 콘텐츠를 원형 화면 중앙의 사각형 영역에 넣고 사각형 화면에서는 이런 콘텐츠가 무시됩니다. BoxInsetLayout의 사용 방법에 대한 자세한 내용은 저희 개발자 안내서에서 형태 인식 레이아웃 섹션을 참조하세요.

BoxInsetLayout을 사용하지 않은 경우
BoxInsetLayout을 사용한 경우

WatchViewStub은 이제 안녕, 반가워요 layout-round!

개발자들은 처음부터 WatchViewStub을 사용해서 사각형 시계와 원형 시계의 레이아웃을 각각 다르게 지정할 수 있었습니다. Android Wear API 23에서는 이 작업이 한결 쉬워졌습니다. 개발자들은 서로 다른 레이아웃을 layout-round 및 layout 폴더에 넣을 수 있습니다. 전에 WatchViewStub을 사용할 때는 개발자들이 뷰 요소들을 연결하기 전에 레이아웃이 확장되기를 기다려야 했으므로 코드가 상당히 복잡했습니다. -round 식별자를 사용하면 이런 복잡성을 없앨 수 있습니다.

Android Wear API 23 이전 - WatchViewStub(4개 파일)

1. layout/activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>  
 <android.support.wearable.view.WatchViewStub    
     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:id="@+id/watch_view_stub"  
     android:layout_width="match_parent"  
     android:layout_height="match_parent"  
     app:rectLayout="@layout/rect_activity_main"  
     app:roundLayout="@layout/round_activity_main"  
     tools:context="com.android.example.watchviewstub.MainActivity"  
     tools:deviceIds="wear"></android.support.wearable.view.WatchViewStub>

2. layout/rect_activity_main.xml - 사각형 시계 레이아웃
3. layout/round_activity_main.xml - 원형 시계 레이아웃
4. MainAcitivity.java

  
 protected void onCreate(Bundle savedInstanceState) {  
   super.onCreate(savedInstanceState);  
   setContentView(R.layout.activity_main);  
   final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);  
   stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {  
     @Override  
     public void onLayoutInflated(WatchViewStub stub) {  
       mTextView = (TextView) stub.findViewById(R.id.text);  
     }  
   });  
 }  


 

 Android Wear API 23 이후 - layout-round(3개 파일)


1. layout-notround/activity_main.xml - 사각형 시계 레이아웃
2. layout-round/activity_main.xml - 원형 시계 레이아웃
3. MainAcitivity.java

 protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
     mTextView = (TextView) findViewById(R.id.text);    
 }  


그렇더라도 WatchViewStub은 Android Wear 지원 라이브러리의 일부이기 때문에, 현재의 코드에서 이것을 사용하더라도 실패를 야기할 만한 변경은 아니며, 편리한 때에 코드를 다시 쓸 수 있습니다. -round 식별자 외에 개발자들은 리소스를 구분하기 위해 -notround 식별자도 사용합니다. 그렇다면 기본 레이아웃을 사용할 자리에 왜 이것을 사용할까요? 스타일 문제 때문입니다. 여러 가지 레이아웃이 섞여 있다면, 다음과 같은 레이아웃 정리 방법을 생각해봐야 합니다.

  • layout/ - 원형 및 사각형 화면에 모두 사용할 수 있는 레이아웃
  • layout-round/ and layout-notround/ - 화면 형태에 특정한 레이아웃


 

원형 시계 개발을 위한 훨씬 좋은 방법: values-round/dimens.xml

여러 개의 레이아웃 파일을 유지한다는 것은 골치 아픈 일일 수 있습니다. 화면 요소를 추가할 때마다 모든 레이아웃 파일들을 열어 이것을 추가해야 합니다. 모바일 기기에서는 대개 휴대폰이나 태블릿에 대한 다양한 레이아웃을 지정하기 위해서만 이렇게 처리하고, 각기 다른 전화 해상도를 위해 이렇게 하는 경우는 드뭅니다. 시계의 경우 원형 화면과 사각형 화면 간의 레이아웃이 크게 다르지 않는 한(지금껏 필자가 본 바로는 매우 드문 일임), 다른 dimens.xml을 대신 사용하는 방법을 고려해야 합니다.
필자는 -round 식별자를 실험하면서 원형 시계와 사각형 시계를 빌드하는 가장 쉬운 방법은 사실 values/dimens.xml과 values-round/dimens.xml을 명시하는 것이라는 것을 알게 되었습니다. 각기 다른 패딩 설정을 지정함으로써 같은 layout.xml 파일과 두 개의 dimens 파일(사각형과 원형을 위해 각각 하나씩)을 사용하여 아래와 같은 레이아웃을 작성할 수 있었습니다. 필자가 사용한 값들은 이 레이아웃에 적합하지만, 여러분은 여러 값을 사용해보고 어떤 값이 가장 알맞은지 스스로 확인해야 합니다.

values-round/dimens.xml values/dimens.xml

 <dimen name="header_start_padding">36dp</dimen>  
 <dimen name="header_end_padding">22dp</dimen>  
 <dimen name="list_start_padding">36dp</dimen>  
 <dimen name="list_end_padding">22dp</dimen>  

 <dimen name="header_start_padding">16dp</dimen>  
 <dimen name="header_end_padding">16dp</dimen>  
 <dimen name="list_start_padding">10dp</dimen>  
 <dimen name="list_end_padding">10dp</dimen>  

API 23이 소개되기 전에는, 이와 같이 하려면 화면 상의 모든 요소에 대해 각각 다른 치수를 일일이 수작업으로 지정하는 상당량의 상용구 코드가 필요했을 것입니다. 이제 -round 식별자 덕분에 API 23에서 쉽게 이 작업을 할 수 있으며, 이것이 필자가 가장 좋아하는 원형/사각형 레이아웃 빌드 방법입니다.

턱을 잊지 말 것!

어떤 시계에는 다른 원형 화면에 삽입 요소("턱"이라고도 함)가 있습니다. 그러면 어떻게 코드를 세련되게 유지하면서 멋진 레이아웃을 빌드할 수 있을까요? 이 디자인을 주목해 보세요.


activity_main.xml
 <FrameLayout  
   ...>  
   <android.support.wearable.view.CircledImageView  
     android:id="@+id/androidbtn"  
     android:src="@drawable/ic_android"  
     .../>  
   <ImageButton  
     android:id="@+id/lovebtn"  
     android:src="@drawable/ic_favourite"  
     android:paddingTop="5dp"  
     android:paddingBottom="5dp"  
     android:layout_gravity="bottom"  
     .../>  
 </FrameLayout>  
아무런 조치도 하지 않으면 하트 모양 버튼이 턱 안으로 사라질 것입니다. 다행히도, fitsSystemWindows를 사용해서 이 문제를 쉽게 수정할 수 있습니다.

 <ImageButton  
     android:id="@+id/lovebtn"  
     android:src="@drawable/ic_favourite"  
     android:paddingTop="5dp"  
     android:paddingBottom="5dp"  
    android:fitsSystemWindows="true"  
     .../>  

관찰력이 예리한 사람이라면(아래에서 “fitsSystemWindows=”true”” 밑에 보이는, 화면의 중간 이미지), 조금 전에 넣은 상단 및 하단 패딩이 사라진 것을 알아차렸을 것입니다. 이것은 fitsSystemWindows를 사용하는 주요 역효과 중 하나입니다. fitsSystemWindows가 시스템 창에 맞추기 위해 패딩을 무시하기 때문이지요. 그러면 이것을 어떻게 바로잡을까요? 패딩을 InsetDrawables로 대체하면 됩니다.
inset_favourite.xml

 <inset  
   xmlns:android="http://schemas.android.com/apk/res/android"  
   android:drawable="@drawable/ic_favourite" 
   android:insetTop="5dp"  
   android:insetBottom="5dp" />  


activity_main.xml

 <ImageButton  
     android:id="@+id/lovebtn"  
     android:src="@drawable/inset_favourite"  
     android:paddingTop="5dp"  
     android:paddingBottom="5dp"  
     android:fitsSystemWindows="true"  
     .../>  

레이아웃에서의 패딩 설정이 무시되기는 하겠지만, 이 불필요한 코드를 제거하면 코드가 더 깔끔해집니다.

아무 것도 안 한 경우
fitsSystemWindows=”true”
fitsSystemWindows=”true”
및 InsetDrawable 사용
선언을 통해 xml을 사용할 때 가능한 것보다 더 많은 제어가 필요하다면, 프로그래밍으로 레이아웃을 조정할 수도 있습니다. 턱의 크기를 확보하려면 레이아웃의 가장 바깥쪽에 있는 뷰에 View.OnApplyWindowInsetsListener를 연결해야 합니다. 또한, v.onApplyWindowInsets(insets)를 호출하는 것도 잊지 마세요. 그렇지 않으면, 새 리스너가 삽입 요소를 소멸시켜 삽입 요소에 반응하는 내부 요소들이 반응을 보이지 않게 됩니다.

프로그래밍으로 화면의 턱 크기 구하기
MainActivity.java

 private int mChinSize;  
 protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.activity_main);  
     // find the outermost element  
     final View container = findViewById(R.id.outer_container);  
     // attach a View.OnApplyWindowInsetsListener  
     container.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {  
         @Override  
         public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {  
             mChinSize = insets.getSystemWindowInsetBottom();  
             // The following line is important for inner elements which react to insets  
             v.onApplyWindowInsets(insets); 
             return insets; 
     } 
   }); 
 }  


끝으로 언급하지만 역시 중요한 점으로, 코드를 꼭 테스트하세요! 저희는 지난해 이래로 더욱 쉽고 빠른 테스트를 위해 턱이 있는 Android Wear 기기에 다수의 기기 이미지를 포함했습니다.

맞지 않는 것은 이제 그만!

Android Wear는 언제나 사용자들이 원하는 것을 착용할 수 있도록 해왔습니다. 이를 가능하게 하는 주요 부분은 둥근 화면입니다. API 23과 -round 리소스 식별자의 사용으로 둥근 시계와 사각형 시계를 빌드하기가 그 어느 때보다도 쉬워졌습니다. 멋진 코드가 든든히 뒷받침해주는 덕택에 누리는 즐거운 경험이지요!

추가 리소스

Ian Lake왜 시스템 창에 맞춰야 하는가?(Why would I want to fitsSystemWindows?) - 그 한계를 포함하는 이 강력한 도구의 우수 사용 사례. Wayne PiekarskiScreenInfo 유틸리티 - DPI, 턱 크기 등 디스플레이에 대한 유용한 정보가 들어 있습니다.

반응형

댓글