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

머터리얼 컴포넌트 (MDC) 1.2에서 추가된 위젯 사용해보기

by 아이엔 / ienground 2020. 8. 7.

머터리얼 디자인 컴포넌트, 줄여서 MDC의 1.2.0 버전이 정식으로 공개되었고 이에 따라 새롭게 추가된 위젯 및 클래스를 연습할 겸 글을 쓰는 중. Slider, RangeSlider VS Seekbar / ShapableImageView / MaterialColors

 

Slider, RangeSlider VS Seekbar

 

초록색은 기존에 쓰던 Seekbar이고 보라색에 핸들이 하나 있는 건 Slider, 두 개 있는 건 RangeSlider이다. 이전 Seekbar는 최솟값은 항상 0이며 최댓값은 설정 가능하고, Step은 자바/코틀린단에서 했어야 했다고 하는데, 이 Slider와 RangeSlider는 valueFrom, valueTo, 그리고 stepSize 설정이 xml 파일에서 바로 가능하다는게 차이점이다.

 

더불어 RangeSlider와 같이 범위를 설정하는 경우 이전 기본 라이브러리에서 제공하지 않아 외부 라이브러리를 사용해야 했으나, 이 RangeSlider의 사용으로 외부 라이브러리를 사용하지 않아도 통일된 디자인으로 valueFrom, valueTo, stepSize와 array 설정으로 초기 범위 설정이 가능하다.

 

<com.google.android.material.slider.Slider
    android:id="@+id/slider"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginEnd="16dp"
    android:valueFrom="0"
    android:valueTo="100"
    android:stepSize="5"/>
<com.google.android.material.slider.RangeSlider
    android:id="@+id/range"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginEnd="16dp"
    android:valueFrom="0"
    android:valueTo="100"
    android:stepSize="5"
    app:values="@array/initial_slider_values"/>
    
<!-- arrays.xml -->
<resources>
    <array name="initial_slider_values">
        <item>20.0</item>
        <item>70.0</item>
    </array>
</resources>

RangeSlider 코드를 보면 app:values라는 attribute가 있다. 이 values는 초기 범위 값을 넣는 것인데, 이건 레이아웃단에서 넣으면 array를 하나 만들어야 돼서 귀찮다. 이건 자바나 코틀린 코드에서 해주는 게 편했다.

slider.valueFrom = 0.0f
slider.valueTo = 100.0f

range.values = listOf(20f, 50f)

당연하겠지만 slider, range의 각종 속성을 설정해주는 것도 당연히 가능했다.

 

ShapableImageView

 

이제까지 사용했던 모든 원형의 ImageView는 외부 라이브러리를 import해서 사용하였는데, ShapableImageView는 style을 적용할 수 있는 ImageView같은 것이였다. 그 때문에 따로 외부 라이브러리를 사용하지 않고도 원형의 ImageView를 만들 수 있는 이점이 있다.

 

그러나 생각보다 엄청 좋지는 않았는데, 그 이유 중 하나는 style을 여러 개 만들어 줘야 해서 귀찮기 때문이다. app:shape와 같은 attribute를 추가해줬으면 좀 덜 귀찮았으려나?

 

<!-- shapes.xml -->

<resources>
    <style name="ShapeAppearanceOverlay.App.CornerSize50Percent" parent="">
        <item name="cornerSize">50%</item>
    </style>
</resources>
<!-- styles.xml -->
<style name="Widget.App.ShapeableImageView" parent="Widget.MaterialComponents.ShapeableImageView">
    <item name="shapeAppearance">?attr/shapeAppearanceSmallComponent</item>
    <item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.App.CornerSize50Percent</item>
    <item name="strokeColor">?attr/colorPrimary</item>
</style>

스타일 이름은 아무래도 상관없고, cornerSize를 50%나 25%로 설정했다. 그리고 styles.xml에서 Widget.MaterialComponents.ShapeableImageView를 상속하는 새로운 스타일을 만들고, 오버레이를 조금 전에 만든 shapes.xml의 새로운 스타일로 지정한다. 그 후 선 색깔이나 선 굵기(strokeWidth)와 같은 설정을 해 줄 수 있었다.

 

MaterialColors

 

MaterialColors 클래스는 getColor와 layer로 색(Int)을 반환하는데, getColor는 ContextCompat.getColor(context, colorId)처럼 Context를 요구하는 것도 있지만 view를 요구한다. layer는 view를 요구하는 메소드밖에 없다. 

 

getColor(view, attribute_id)로 이루어졌으며 현재 뷰의 스타일에서 컬러를 얻어오는 것으로 보인다. 참고로 액티비티에서 현재 뷰를 얻어오려면 코틀린 기준 아래처럼 하면 된다.

val view = window.decorView.rootView

여튼 getColor는 그렇고, layer는 말 그대로 두 색이 겹쳐졌을 때의 색을 반환한다. 때문에 인자가 세 개 혹은 네 개이다. 인자가 세 개인 경우 view, background color, overlay color. 네 개인 경우 view, background color, overlay color, 그리고 overlay alpha(Float)이다. 세 개인 경우 overlay alpha는 기본적으로 1f = 100%이다. 

 

이 단락 제목 바로 아래 올려져 있는 사진은 layer의 예시인데, 아래에 있는 ImageView 속 색이 각각 background color가 colorAccent이고 overlay color가 colorPrimary인 색이다. 그런데 overlay alpha가 0.3f, 0.1f, 0.9f이다.

 

대충 그렇게 색을 포토샵 켜서 섞을 필요 없이 기본적으로 제공해준다는 걸 대충 알고만 있으면 언젠간 쓸 것 같다.

 

* 모든 스크린샷 및 코드 테스트는 직접 했습니다.

 

참고한 글 : https://medium.com/google-design/material-components-for-android-1-2-0-is-now-available-aade483ed841