IT_Programming/Android_Java

[펌] 모든 디바이스를 위한 머티리얼 디자인 - AppCompat 라이브러리

JJun ™ 2015. 7. 19. 22:30



 출처: http://googledevkr.blogspot.kr/2014/10/appcompat-v21-material-design-for-pre.html





새로운 안드로이드 5.0 롤리팝 SDK 에는 머티리얼디자인을 지원하기 위한 새로운 위젯과 기능이 포함되어 있습니다.
이와 동시에,
 이전 안드로이드 플랫폼에서도 머티리얼 디자인을 적용할 수 있도록 서포트 라이브러리가 확장되었습니다. 


AppCompat 라이브러리에 많은 업데이트가 있었으며, 이와 함께 RecyclerView, CardView, Palette 라이브러리도 정식으로 공개되었습니다.

AppCompat 라이브러리를 이용해 어떻게 여러분의 앱에 머티리얼디자인을 적용할 수 있을지 살펴보도록 하겠습니다.



AppCompat 의 새로운 기능들

처음 AppCompat 라이브러리는 아이스크림 샌드위치에 포함된 액션바 API와 기능을 이전 버전의 안드로이드에서도 사용할 수 있도록
지원하기 위해 시작되었습니다. 이와 마찬가지로, 새롭게 업데이트된 AppCompat v21 라이브러리는 최신 안드로이드 5.0 에서 제공하는 API 와
기능들을 이전 버전의 안드로이드에서 사용할 수 있도록 만들어 줍니다.


이번 버전에서는 새로운 Toolbar 위젯이 추가되었습니다. Toolbar는 좀 더 일반적인 형태의 액션바입니다.
매우 유연하게 설계되었고, 개발자 여러분은 필요에 따라 Toolbar의 모습, 형태, 동작 방식등을 쉽게 변경할 수 있습니다.
Toolbar는 다른 안드로이드 뷰와 마찬가지로 여러분이 관리하는 뷰 계층 구조에 포함됩니다.
때문에, 개발자 여러분은 큰 어려움없이 앱 내의 다른 뷰와 Toolbar가 서로 상호작용하게 만들 수 있고, 애니매이션 효과를 부여하거나,
화면 스크롤 이벤트에 Toolbar가 반응하도록 만들 수 있습니다. 물론 Toolbar를 기존의 표준적인 액션바처럼 사용할 수 있으며,
이 경우 개발자 여러분이 기존에 액션바를 위해 지정한 모든 메뉴가 Toolbar위에 동일하게 나타납니다.


개발자 여러분은 사실 이미 새로운 AppCompat 라이브러리와 Toolbar 위젯을 사용하고 계실 수도 있습니다.
지난 몇 주간 Play 스토어, 뉴스 스탠드와 같은 다양한 구글 앱들이 최신 AppCompat 라이브러리를 이용하여 업데이트 되었습니다.
또한, 위 스크린샷에서 확인하실 수 있 듯이
 오픈소스로 공개된 구글 I/O 안드로이드 앱에도 적용되었습니다.


AppCompat 적용하기 

Gradle 을 사용하고 계신 경우, build.gradle 파일에 다음과 같은 내용을 추가하시면 됩니다.

dependencies {
    compile "com.android.support:appcompat-v7:21.0.+"
}



처음으로 AppCompat 를 적용하는 경우

현재 AppCompat 라이브러리를 사용하지 않거나, 처음부터 앱을 만들 예정인 경우 다음 단계를 거쳐 AppCompat 라이브러리를 적용할 수 있습니다.


  • 모든 엑티비티는 반드시 ActionBarActivity 를 확장해야 합니다. ActionBarActivity 는 v4 서포트 라이브러리에 포함된 FragmentActivity 를 확장하고 있기 때문에 Fragment를 계속 사용하실 수 있습니다.
  • 사용하는 모든 테마는 반드시 Theme.AppCompat 를 상속받아야 합니다. AppCompat 테마는 기존 시스템 테마와 마찬가지로 Light 와 NoActionBar 같은 다양한 옵션을 지원합니다.
  • 네비게이션을 목적으로 Toolbar 에 포함되는 Spinner 와 같이 Toolbar 상에 추가될 뷰를 생성할 때는 반드시 getSupportActionBar().getThemedContext() 메서드를 이용하여, 액션바 테마가 적용된 컨텍스트를 받아와 사용해야 합니다.
  • MenuItem 를 이용해 getActionProvider 와 같은 액션 기능에 관한 메서드를 호출할 때는 반드시 서포트 라이브러리에 포함된 MenuItemCompat 클래스의 정적 메서드를 활용해야 합니다.


보다 자세한 내용은 안드로이드 개발자 문서의 Action Bar API 가이드 항목을 살펴보시기 바랍니다.



AppCompat 를 이미 사용중인 기존 앱에 적용하는 경우

특별한 작업이 필요하지 않습니다. 한 가지, 더 이상 v14 이상 버전을 위해, 액션바 스타일을 위한 속성을 별도로 지정해서 관리할 필요가 없으며,
하나의 테마 파일을 통해 앱의 스타일을 정의할 수 있습니다. 액션바에 적용되는 모든 속성들은 이제 일괄적으로 AppCompat 라이브러리에 정의된
속성들이 적용됩니다. ('android:actionBarStyle' 를 중복해서 선언하지 않아도 됩니다.)

values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
    <!-- Set AppCompats actionBarStyle -->
    <item name="actionBarStyle">@style/MyActionBarStyle</item>
    <!-- Set AppCompat’s color theming attrs -->
    <item name=”colorPrimary”>@color/my_awesome_red</item>
    <item name=”colorPrimaryDark”>@color/my_awesome_darker_red</item>
    
    <!-- The rest of your attributes -->
</style>



테마 적용하기

AppCompat 에는 새로운 앱의 칼라 팔레트 를 지정할 수 있는 새로운 속성이 추가되었습니다.
다음과 같이
 Primary 색상과 Accent 색상 속성을 지정하면 손쉽게 앱의 브랜드 칼라를 전체적으로 적용할 수 있습니다.

values/themes.xml:
<style name="Theme.MyTheme" parent="Theme.AppCompat.Light">
    <!-- colorPrimary is used for the default action bar background -->
    <item name=”colorPrimary”>@color/my_awesome_color</item>
    <!-- colorPrimaryDark is used for the status bar -->
    <item name=”colorPrimaryDark”>@color/my_awesome_darker_color</item>
    <!-- colorAccent is used as the default value for colorControlActivated,
         which is used to tint widgets -->
    <item name=”colorAccent”>@color/accent</item>
    <!-- You can also set colorControlNormal, colorControlActivated
         colorControlHighlight, and colorSwitchThumbNormal. -->
    
</style>


안드로이드 5.0 이상 버전에서, AppCompat 라이브러리는 지정된 속성 값들을 자동으로 프레임워크 속성으로 변환해 적용합니다. 


또한, 이전 버전의 안드로이드에서는 지정된 색상이 최대한 앱에 반영될 수 있도록 액션바와 현재 지원되고 있는
위젯들에 적절히 속성값을 적용합니다. 지원되는 위젯의 목록은 바로 다음 이어지는 항목에서 확인하실 수 있습니다.



위젯의 색상 변경 (Widget Tinting)

안드로이드 5.0 에서는 모든 위젯들이 칼라 팔레트 정보에 맞추어 그 색상이 적절히 변경됩니다.
롤리팝에는 동적으로 Drawable 에 색상을 입힐 수 있는 ‘Tinting’ 기능과, Drawable 에서 테마의 속성을 참고할 수 있는 기능이 추가되었으며,
두 가지 기능을 통해 안드로이드 프레임워크는 개발자가 지정한 색상을 모든 위젯에 반영할 수 있습니다.


이전 버전의 안드로이드에서도 앱의 전체적인 모습을 일관되게 유지할 수 있도록, 널리 사용되는 다음 위젯들의 색상은 개발자가 정의한 칼라 팔레트 속성에 맞추어 적절히 변경됩니다.지원되는 위젯 목록은 AppCompat 라이브러리가 업데이트 될 때 마다 계속 늘어날 것 입니다.



위젯에 색상을 적용하기 위해 개발자 여러분이 추가로 해야할 작업은 없습니다.
다만, 몇 가지 주의사항이 있는데 아래 이어질 FAQ 항목을 참고하시기 바랍니다.




Toolbar 위젯



AppCompat 를 통해 안드로이드 5.0 롤리팝에서 새롭게 추가된 Toolbar 위젯을 이전 버전에서도 동일하게 사용할 수 있습니다.
Toolbar 는
 android.support.v7.widget.Toolbar 클래스에 구현되어 있으며, 다음과 같이 두 가지 형태로 활용할 수 있습니다.


  • Toolbar를 액션바처럼 사용합니다. 액션바에서 제공하는 메뉴 생성이나 ActionBarDrawerToggle 기능들을 사용하면서 동시에 그 모습을 조금 더 자유롭게 꾸미고 싶은 경우가 해당됩니다.
  • Toolbar를 독립적으로 사용합니다. 하나 이상의 Toolbar가 필요하거나 화면 전체 너비 보다 작은 Toolbar를 사용해야 하는 등, 여러분의 앱에 액션바를 사용하는 것이 적절하지 않은 경우 Toolbar를 독립적인 위젯으로 활용할 수 있습니다.



액션바 처럼 사용하기

Toolbar를 액션바 처럼 사용하기 위해서는 우선 시스템에서 제공되는 액션바를 제거해야 합니다.
손 쉽게 Theme.AppCompat.NoActionBar 테마를 적용하면 액션바를 제거할 수 있습니다.
그리고 XML 에 다음과 같은 방식으로 Toolbar를 생성합니다.

<android.support.v7.widget.Toolbar
    android:id=”@+id/my_awesome_toolbar”
    android:layout_height=”wrap_content”
    android:layout_width=”match_parent”
    android:minHeight=”?attr/actionBarSize”
    android:background=”?attr/colorPrimary” />


높이와 너비, 배경색등은 원하는 대로 적용하실 수 있습니다. 위에서 사용한 값들은 그저 하나의 예시에 불과합니다.
Toolbar는 일반적인 ViewGroup 이기 때문에 여러분이 원하는 곳 어디에든지 위치시킬 수 있습니다.


다음으로, 엑티비티나 프레그먼트 코드 상에 Toolbar가 액션바 처럼 사용되도록 선언합니다.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.blah);
    Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);
}


이 후, 안드로이드의 표준적인 메뉴 생성 콜백을 통해 생성되는 모든 메뉴는 Toolbar 위에 표시됩니다.



독립적으로 사용하기

Toolbar를 독립적으로 사용하기 위해서는 Toolbar가 액션바처럼 동작하도록 선언하지 않습니다.
여러분은 AppCompat 의 어떤 테마든 사용할 수 있고 (액션바가 적용된 테마를 포함하여), 시스템에서 제공하는 액션바와 함께
Toolbar 를 사용할 수 있습니다. 


다만, 이 경우 Toolbar를 생성할 때, 개발자 여러분이 직접 올바른 컨텐츠와 액션을 포함하여 Toolbar를 생성해야 합니다.
예를 들어, Toolbar에 메뉴를 추가하고 싶은 경우, 다음과 같이 Toolbar를 통해 직접 메뉴를 생성하고, 이벤트를 처리하위 위한 콜백을 구현해야 합니다.

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.blah);
    Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
    // Set an onMenuItemClickListener to handle menu item clicks
    toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem item) {
            // Handle the menu item
            return true;
        }
    });
    // Inflate a menu to be displayed in the toolbar
    toolbar.inflateMenu(R.menu.your_toolbar_menu);
}


Toolbar를 이용해 훨씬 더 다양한 일들을 할 수 있습니다.
보다 자세한 내용은 안드로이드 개발자 문서의
 Toolbar API reference 항목을 살펴보시기 바랍니다.



스타일링

Toolbar 는 액션바와 달리 뷰에 직접 원하는 스타일을 적용할 수 있습니다.
예를 들어 Toolbar 를 액션바처럼 사용하고자 한다면 다음과 같이 정의할 수 있습니다.

<android.support.v7.widget.Toolbar  
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:minHeight="?attr/actionBarSize"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />


또한, “DarkActionBar” 테마 (어두운 컨텐츠, 밝은 색의 오버플로우 메뉴) 는 Toolbar 의 theme 와 popupTheme 속성을
다음과 같이 지정해 구현할 수 있습니다.

<android.support.v7.widget.Toolbar
    android:layout_height=”wrap_content”
    android:layout_width=”match_parent”
    android:minHeight=”@dimen/triple_height_toolbar”
    app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />



SearchView 위젯

AppCompat 에는 롤리팝의 최신 SearchView API 가 포함되어 있습니다.
훨씬 더 쉽게 커스터마이징할 수 있으며 원하는 스타일을 적용할 수 있습니다.
이전의 SearchView 에서 사용된 속성 값 대신 새로운 롤리팝 스타일의 속성 값들이 사용됩니다.


SearchView는 다음과 같은 속성들을 이용하여 스타일을 변경할 수 있습니다.

values/themes.xml:
<style name=”Theme.MyTheme parent=”Theme.AppCompat”>
    <item name=”searchViewStyle”>@style/MySearchViewStyle</item>
</style>
<style name=”MySearchViewStyle parent=”Widget.AppCompat.SearchView”>
    <!-- Background for the search query section (e.g. EditText) -->
    <item name="queryBackground">...</item>
    <!-- Background for the actions section (e.g. voice, submit) -->
    <item name="submitBackground">...</item>
    <!-- Close button icon -->
    <item name="closeIcon">...</item>
    <!-- Search button icon -->
    <item name="searchIcon">...</item>
    <!-- Go/commit button icon -->
    <item name="goIcon">...</item>
    <!-- Voice search button icon -->
    <item name="voiceIcon">...</item>
    <!-- Commit icon shown in the query suggestion row -->
    <item name="commitIcon">...</item>
    <!-- Layout for query suggestion rows -->
    <item name="suggestionRowLayout">...</item>
</style>


물론 이런 값들을 모두 수정할 필요는 없습니다. 대부분의 경우 기본 스타일을 사용하는 것 만으로 충분합니다.




새로운 머티리얼 테마의 시대가 다가오고 있습니다.

이 포스트를 통해 AppCompat을 사용하는 법과 멋진 머티리얼 디자인 앱을 만드는 데에 도움을 받으셨길 바랍니다. AppCompat이나 다른 라이브러리 지원에 대해 질문이 있거나 관련된 문서를 어디서 더 볼 수 있는지 궁금하시다면 구글플러스, 트위터 등을 통해 알려주시기 바랍니다.



FAQ


왜 제 롤리팝 이전 버전 기기에서는 EditText (혹은 상단 위젯 리스트)가 색이 바뀌지 않나요?
AppCompat 에서 위젯의 색을 변경하는 Tinting 기능은 레이아웃이 생성되는 시점을 가로채 기존 위젯을 색상 변경을 인지할 수 있는
새로운 위젯을 적용하는 방식으로 구현되어 있습니다. 대부분의 경우 별 문제없이 동작하지만 다음과 같은 경우 문제가 발생할 수 있습니다.


  • 기존 위젯을 확장한 커스텀 뷰를 사용하는 경우 (예: EditText를 확장한 경우)
  • LayoutInflater 를 통하지 않고 다른 방식으로 위젯을 생성한 경우 (예: new EditText() )


색상 변경을 인지할 수 있는 위젯들은 아직 구현이 끝나지 않았기 때문에 숨겨져 있는 상태입니다. 구
현 내용이 변경될 수 있으며 해당 위젯들을 직접 활용하지 말기를 바랍니다.




롤리팝 이전 버전에서 X 위젯들은 왜 머티리얼 디자인 스타일로 바뀌지 않나요?

현재는 가장 보편적인 위젯 몇 가지만 업데이트 된 상태입니다.
AppCompat이 업데이트 될 때 다른 위젯들도 추가로 수정될 예정입니다.




안드로이드 롤리팝에서 android:windowContentOverlay를 null로 설정했는데, 왜 제 액션 바는 그림자가 있나요?

롤리팝에서 액션 바의 그림자는 새로운 Elevation API를 이용해 제공되고 있습니다.
그림자를 제거하려면 getSupportActionBar().setElevation(0); 메서드를 호출하거나 액션 바 스타일에서 Elevation 속성을 0으로 설정하세요.




왜 롤리팝 이전 버전에서는 잔물결(ripples)이 나타나지 않나요?

RippleDrawable 이 부드럽게 동작하기 위해서는 안드로이드 5.0의 새로운 RenderThread가 필요합니다.
이전 버전의 안드로이드들의 퍼포먼스를 최적화 하기 위해서 안드로이드 5.0 이전 버전에서는 RippleDrawable 가 제거되었습니다.




AppCompat 를 활용할 때 Preference 는 어떻게 구현해야 하나요?

API v11+ 기기를 대상으로 하고 있다면, PreferenceFragment를 활용할 수 있습니다. 그 이전의 기기들의 경우 머티리얼 디자인이 적용되지 않은 PreferenceActivity를 사용해야 합니다.