MDC-104 Android: 머티리얼 고급 구성요소 (Java)

1. 소개

logo_components_color_2x_web_96dp.png

머티리얼 구성요소(MDC)를 통해 개발자는 머티리얼 디자인을 구현할 수 있습니다. Google의 엔지니어와 UX 디자이너로 구성된 팀에서 만든 MDC는 아름답고 기능적인 수십 가지의 UI 구성요소가 특징이며 Android, iOS, 웹, Flutter.material.io/develop에서 제공됩니다.

Codelab MDC-103에서는 머티리얼 구성요소 (MDC)의 색상, 고도, 서체를 맞춤설정하여 앱 스타일을 지정했습니다.

Material Design 시스템의 구성요소는 일련의 사전 정의된 태스크를 실행하며 버튼과 같은 특정 특성을 가집니다. 하지만 버튼은 사용자가 동작을 진행하는 단순한 방법에 불과하지 않습니다. 버튼은 사용자에게 상호작용 방식이며 터치나 클릭 시 특정 동작이 발생함을 알려주는 형태, 크기, 색상의 시각적 표현이기도 합니다.

머티리얼 디자인 가이드라인에서는 디자이너 관점에서 구성요소를 설명합니다. 그리고 플랫폼에서 사용할 수 있는 다양한 기본 기능은 물론 각 구성요소를 구성하는 개별 요소도 설명합니다. 예를 들어 배경화면에는 뒷면 레이어와 콘텐츠, 전면 레이어와 콘텐츠, 모션 규칙, 디스플레이 옵션이 포함되어 있습니다. 이러한 각 구성요소는 각 앱의 요건, 사용 사례 및 콘텐츠에 따라 맞춤설정할 수 있습니다. 대부분의 경우 이러한 부분은 플랫폼 SDK의 기존 뷰, 컨트롤 및 기능에 해당합니다.

머티리얼 디자인 가이드라인에는 많은 구성요소가 나열되어 있지만 일부는 재사용 가능 코드에 사용할 만하지 않기 때문에 MDC에 없습니다. 기존 코드를 사용해 환경을 직접 만들어 앱 스타일을 맞춤설정할 수 있습니다.

빌드할 항목

이 Codelab에서는 Shrine에 배경화면을 추가합니다. 그러면 비대칭 그리드에 표시된 제품을 카테고리별로 필터링합니다. 다음을 사용합니다.

  • 도형
  • 모션
  • 기존 Android SDK 클래스

21c025467527a18e.png dcde66003cd51a5.png

이 Codelab의 MDC-Android 구성요소

  • 도형

필요한 항목

  • Android 개발에 관한 기본 지식
  • Android 스튜디오(아직 다운로드하지 않은 경우 여기에서 다운로드)
  • Android Emulator 또는 기기(Android 스튜디오를 통해 사용 가능)
  • 샘플 코드(다음 단계 참고)

귀하의 Android 앱 빌드 경험 수준을 평가해 주세요.

<ph type="x-smartling-placeholder"></ph> 초보자 중급 숙련도

2. 개발 환경 설정

MDC-103에서 계속 진행하시겠어요?

MDC-103을 완료했다면 이 Codelab을 위한 코드가 준비된 것입니다. 3단계로 건너뜁니다.

처음부터 새로 시작

시작 Codelab 앱 다운로드

시작 앱은 material-components-android-codelabs-104-starter/java 디렉터리에 있습니다. 시작하기 전에 해당 디렉터리로 cd하세요.

...또는 GitHub에서 클론

이 Codelab을 GitHub에서 클론하려면 다음 명령어를 실행하세요.

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 104-starter

Android 스튜디오에서 시작 코드 로드

  1. 설정 마법사가 완료되고 Welcome to Android Studio 창이 표시되면 Open an existing Android Studio project를 클릭합니다. 샘플 코드를 설치한 디렉토리로 이동하고 java -> Shrine (또는 컴퓨터에서 shrine을 검색)하여 Shrine 프로젝트를 엽니다.
  2. Android 스튜디오 창 하단의 활동 표시기에 나타나는 것처럼 Android 스튜디오가 프로젝트를 빌드하고 동기화할 때까지 잠시 기다립니다.
  3. 이 시점에서 Android 스튜디오에 아래와 같은 빌드 오류가 발생할 수 있습니다. Android SDK나 빌드 도구가 누락되었기 때문입니다. Android 스튜디오의 안내를 따라 이러한 항목을 설치/업데이트하고 프로젝트를 동기화합니다.

F5H6srsw_5xOPGFpKrm1RwgewatxA_HUbDI1PWoQUAoJcT6DpfBOkAYwq3S-2vUHvweUaFgAmG7BtUKkGouUbhTwXQh53qec8tO5eVecdlo7QIoLc8rNxFEBb8l7RlS-KzBbZOzVhA

프로젝트 종속 항목 추가

프로젝트에는 MDC Android 지원 라이브러리에 대한 종속 항목이 필요합니다. 다운로드한 샘플 코드에는 이 종속 항목이 이미 나열되어 있지만, 다음 단계를 수행하여 확인하는 것이 좋습니다.

  1. app 모듈의 build.gradle 파일로 이동하여 dependencies 블록에 MDC Android 종속 항목이 포함되어 있는지 확인합니다.
api 'com.google.android.material:material:1.1.0-alpha06'
  1. (선택사항) 필요한 경우 build.gradle 파일을 수정하여 다음 종속 항목을 추가하고 프로젝트를 동기화합니다.
dependencies {
    api 'com.google.android.material:material:1.1.0-alpha06'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21"
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:core:1.1.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test:runner:1.2.0-alpha05'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0-alpha05'
}

시작 앱 실행

  1. Run / Play 버튼 왼쪽의 빌드 구성이 app인지 확인합니다.
  2. 녹색 실행/재생 버튼을 눌러 앱을 빌드하고 실행합니다.
  3. 사용 가능한 기기에 Android 기기가 이미 나열되어 있으면 Select Deployment Target 창에서 8단계로 건너뜁니다. 나열되어 있지 않으면 Create New Virtual Device를 클릭합니다.
  4. Select Hardware 화면에서 Pixel 2와 같은 휴대전화 기기를 선택한 후 Next를 클릭합니다.
  5. System Image 화면에서 최신 Android 버전(가장 높은 API 수준 권장)을 선택합니다. 설치되어 있지 않은 경우 표시되는 다운로드 링크를 클릭하고 다운로드를 완료합니다.
  6. Next를 클릭합니다.
  7. Android Virtual Device (AVD) 화면에서 설정을 그대로 두고 Finish를 클릭합니다.
  8. 배포 대상 대화상자에서 Android 기기를 선택합니다.
  9. 확인을 클릭합니다.
  10. Android 스튜디오가 앱을 빌드하고 배포한 후 자동으로 대상 기기에서 앱을 엽니다.

완료되었습니다. 기기에서 Shrine 앱이 실행되는 것을 확인할 수 있습니다.

79eaeaff51de5719.png

3. 배경화면 메뉴 추가

배경화면은 앱에서 가장 먼 표면이며 다른 모든 콘텐츠와 구성요소 뒤에 표시됩니다. 레이어는 두 가지 표면, 즉 작업과 필터를 표시하는 후면 레이어와 콘텐츠를 표시하는 전면 레이어로 구성됩니다. 배경화면을 사용하여 탐색 또는 콘텐츠 필터 같은 대화형 정보와 동작을 표시할 수 있습니다.

그리드 콘텐츠 숨기기

shr_product_grid_fragment.xml에서 android:visibility="gone" 속성을 NestedScrollView에 추가하여 제품 콘텐츠를 일시적으로 삭제합니다.

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   android:visibility="gone"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

이 리전에 배경화면을 설치합니다. 상단 앱 바와 배경화면에 표시되는 메뉴 콘텐츠가 구분되지 않도록 배경화면의 색상을 상단 앱 바와 동일한 색상으로 설정합니다.

shr_product_grid_fragment.xml에서 루트 FrameLayoutAppBarLayout 앞에 다음을 첫 번째 요소로 추가합니다.

shr_product_grid_fragment.xml

<LinearLayout
   style="@style/Widget.Shrine.Backdrop"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:gravity="center_horizontal"
   android:orientation="vertical"
   android:paddingTop="100dp"
   android:paddingBottom="100dp">

</LinearLayout>

styles.xml에 다음을 추가합니다.

styles.xml

<style name="Widget.Shrine.Backdrop" parent="">
   <item name="android:background">?attr/colorAccent</item>
</style>

잘하셨습니다. Shrine의 UI에 아름다운 배경화면을 추가했습니다. 다음으로 메뉴를 추가합니다.

메뉴 추가

메뉴는 기본적으로 텍스트 버튼의 목록입니다. 여기에 하나를 추가하겠습니다.

res -> layout 디렉터리에 shr_backdrop.xml라는 새 레이아웃을 만들고 다음을 추가합니다.

shr_backdrop.xml

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_featured_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_apartment_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_accessories_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_shoes_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_tops_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_bottoms_label" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_dresses_label" />

   <View
       android:layout_width="56dp"
       android:layout_height="1dp"
       android:layout_margin="16dp"
       android:background="?android:attr/textColorPrimary" />

   <com.google.android.material.button.MaterialButton
       style="@style/Widget.Shrine.Button.TextButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/shr_account_label" />

</merge>

그리고 이 목록을 <include> 태그를 사용하여 방금 shr_product_grid_fragment.xml에 추가한 LinearLayout에 추가합니다.

shr_product_grid_fragment.xml

<LinearLayout
   style="@style/Widget.Shrine.Backdrop"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:gravity="center_horizontal"
   android:orientation="vertical"
   android:paddingTop="88dp">

   <include layout="@layout/shr_backdrop" />
</LinearLayout>

빌드하고 실행합니다. 홈 화면이 다음과 같이 표시됩니다.

a87a58e2ccddbae5.png

배경화면이 완성되었습니다. 앞서 숨겼던 콘텐츠를 다시 살펴보겠습니다.

4. 형태 추가

이 Codelab에서 Shrine을 변경하기 전에는 주요 제품 콘텐츠가 가장 먼 뒷면에 있었습니다. 배경화면을 추가하면 콘텐츠가 배경화면 앞에 표시되므로 더 강조됩니다.

새 레이어 추가

제품 그리드 레이어를 다시 표시해야 합니다. NestedScrollView에서 android:visibility="gone" 속성을 삭제합니다.

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

왼쪽 상단 모서리에 노치가 있는 전면 레이어의 스타일을 지정해 보겠습니다. 머티리얼 디자인에서는 이런 유형의 맞춤설정을 형태라고 합니다. Material 표면은 다양한 도형으로 표시할 수 있습니다. 형태는 노출 영역에 강조와 스타일을 추가하고, 브랜드 표현에도 사용할 수 있습니다. Material 도형에는 곡선 또는 각진 모서리와 가장자리, 여러 면이 있을 수 있습니다. 형태는 대칭적이거나 불규칙적일 수 있습니다.

도형 추가하기

그리드의 모양을 수정합니다. 맞춤 도형 배경을 제공했지만 이 도형은 Android Marshmallow 이상에서만 올바르게 표시됩니다. Android Marshmallow 이상에서만 NestedScrollViewshr_product_grid_background_shape 배경을 설정할 수 있습니다. 먼저 다음과 같이 코드에서 참조할 수 있도록 idNestedScrollView에 추가합니다.

shr_product_grid_fragment.xml

<androidx.core.widget.NestedScrollView
   android:id="@+id/product_grid"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_marginTop="56dp"
   android:background="@color/productGridBackgroundColor"
   android:elevation="8dp"
   app:layout_behavior="@string/appbar_scrolling_view_behavior">

그런 다음 ProductGridFragment.java에서 프로그래매틱 방식으로 배경을 설정합니다. 다음 로직을 추가하여 return 문 바로 앞에 배경을 onCreateView()의 끝으로 설정합니다.

ProductGridFragment.java

// Set cut corner background for API 23+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    view.findViewById(R.id.product_grid).setBackgroundResource(R.drawable.shr_product_grid_background_shape);
}

마지막으로 productGridBackgroundColor 색상 리소스 (맞춤 도형 배경에서도 사용됨)를 다음과 같이 업데이트합니다.

colors.xml

<color name="productGridBackgroundColor">#FFFBFA</color>

빌드 및 실행:

9cf7a94091438011.png

Shrine에 기본 노출 영역에 맞춤 스타일이 지정된 형태를 부여했습니다. 노출 영역의 고도로 인해 사용자는 전면 흰색 레이어 뒤에 무언가가 있음을 알 수 있습니다. 사용자가 메뉴인 항목을 볼 수 있도록 모션을 추가해 보겠습니다.

5. 모션 추가

모션은 앱에 활기를 불어넣는 방법입니다. 모션은 크고 드라마틱하거나 섬세하고 작을 수 있으며, 그 중간일 수 있습니다. 사용하는 모션 유형은 상황에 적합해야 합니다. 반복되는 규칙 동작에 적용되는 모션은 작고 섬세해야 하므로 주기적으로 너무 많은 시간을 소비하지 않아야 합니다. 다른 상황(예: 사용자가 앱을 처음 열 때)은 더 많은 시선을 끌 수 있으며 사용자에게 앱 사용 방법을 교육하는 데 도움이 될 수 있습니다.

메뉴 버튼에 표시 모션 추가

앞쪽 도형이 아래로 수직 이동하는 동작입니다. NavigationIconClickListener.java에서 시트의 변환 애니메이션을 실행하는 클릭 리스너가 이미 제공되어 있습니다. ProductGridFragment.javasetupToolbar() 메서드 내에서 이 클릭 리스너를 설정할 수 있습니다.

ProductGridFragment.java

toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));

이제 setUpToolbar() 메서드가 다음과 같이 표시됩니다.

ProductGridFragment.java

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }

   toolbar.setNavigationOnClickListener(new NavigationIconClickListener(getContext(), view.findViewById(R.id.product_grid)));
}

빌드하고 실행합니다. 메뉴 버튼을 누릅니다.

46a878bade66f821.png

탐색 메뉴 아이콘을 다시 누르면 메뉴가 숨겨져야 합니다.

전면 레이어의 모션 조정

모션은 브랜드를 표현하는 좋은 방법입니다. 다른 타이밍 곡선을 사용하여 표시 애니메이션이 어떻게 표시되는지 살펴보겠습니다.

다음과 같이 ProductGridFragment.javasetupToolbar()에서 코드를 업데이트하여 보간기를 탐색 아이콘의 클릭 리스너에 전달합니다.

ProductGridFragment.java

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }

   toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
           getContext(),
           view.findViewById(R.id.product_grid),
           new AccelerateDecelerateInterpolator()));
}

이렇게 하면 다른 효과가 나오지 않나요?

6. 브랜드 아이콘

브랜딩된 아이콘도 익숙한 아이콘으로 확장됩니다. 브랜딩된 고유한 스타일을 위해 표시 아이콘을 맞춤설정하고 제목과 병합해 보겠습니다.

메뉴 버튼 아이콘 변경

메뉴 버튼을 변경하여 다이아몬드 디자인이 포함된 아이콘을 표시합니다. Google에서 제공한 새로운 브랜드 아이콘 (shr_branded_menu)을 사용하도록 shr_product_grid_fragment.xml에서 툴바를 업데이트하고 app:contentInsetStartandroid:padding 속성을 설정하여 툴바가 디자이너 사양과 더 일치하도록 합니다.

shr_product_grid_fragment.xml

<androidx.appcompat.widget.Toolbar
   android:id="@+id/app_bar"
   style="@style/Widget.Shrine.Toolbar"
   android:layout_width="match_parent"
   android:layout_height="?attr/actionBarSize"
   android:paddingStart="12dp"
   android:paddingLeft="12dp"
   android:paddingEnd="12dp"
   android:paddingRight="12dp"
   app:contentInsetStart="0dp"
   app:navigationIcon="@drawable/shr_branded_menu"
   app:title="@string/shr_app_name" />

다음과 같이 ProductGridFragment.javasetupToolbar()에서 클릭 리스너를 다시 업데이트하여 메뉴가 열릴 때와 닫힐 때 툴바의 드로어블을 가져옵니다.

ProductGridFragment.java

private void setUpToolbar(View view) {
   Toolbar toolbar = view.findViewById(R.id.app_bar);
   AppCompatActivity activity = (AppCompatActivity) getActivity();
   if (activity != null) {
       activity.setSupportActionBar(toolbar);
   }

   toolbar.setNavigationOnClickListener(new NavigationIconClickListener(
           getContext(),
           view.findViewById(R.id.product_grid),
           new AccelerateDecelerateInterpolator(),
           getContext().getResources().getDrawable(R.drawable.shr_branded_menu), // Menu open icon
           getContext().getResources().getDrawable(R.drawable.shr_close_menu))); // Menu close icon
}

빌드 및 실행:

21c025467527a18e.png dcde66003cd51a5.png

좋은 소식입니다. 배경화면을 표시할 수 있으면 다이아몬드 메뉴 아이콘이 표시됩니다. 메뉴를 숨길 수 있는 경우에는 닫기 아이콘이 대신 표시됩니다.

7. 요약

지금까지 네 가지 Codelab 과정에서 Material 구성요소를 사용하여 브랜드의 개성과 스타일을 표현하는 독특하고 세련된 사용자 환경을 빌드하는 방법을 알아봤습니다.

다음 단계

이 Codelab MDC-104로 이번 Codelab 과정이 끝났습니다. Android 위젯 카탈로그를 방문하면 MDC-Android의 더 많은 구성요소를 살펴볼 수 있습니다.

이 Codelab에 관한 또 다른 도전과제를 위해, Shrine 애플리케이션을 수정하여 배경화면 메뉴에서 카테고리를 선택할 때 표시되는 제품 이미지를 변경합니다.

실제로 작동하는 백엔드를 위해 이 앱을 Firebase에 연결하는 방법을 알아보려면 Firebase Android Codelab을 참조하세요.

적절한 시간과 노력을 들여 이 Codelab을 완료할 수 있었습니다.

매우 동의함 동의함 보통 동의하지 않음 전혀 동의하지 않음

앞으로 머티리얼 구성요소를 계속 사용하고 싶습니다.

<ph type="x-smartling-placeholder"></ph> 매우 동의함 동의함 보통 동의하지 않음 전혀 동의하지 않음