1. 소개
머티리얼 구성요소(MDC)를 통해 개발자는 머티리얼 디자인을 구현할 수 있습니다. Google의 엔지니어와 UX 디자이너로 구성된 팀에서 만든 MDC는 아름답고 기능적인 수십 가지의 UI 구성요소가 특징이며 Android, iOS, 웹, Flutter.material.io/develop에서 제공됩니다. |
MDC-101 Codelab에서는 머티리얼 구성요소(MDC) 두 가지(텍스트 입력란, 버튼)를 사용하여 로그인 페이지를 빌드했습니다. 이제 탐색, 구조, 데이터를 추가하여 이러한 기초를 확장해보겠습니다.
빌드할 항목
이 Codelab에서는 Shrine 앱(의류와 가정용품을 판매하는 전자상거래 앱)의 홈 화면을 빌드합니다. 다음 항목이 포함됩니다.
- 상단 앱 바
- 제품의 그리드 목록
이 Codelab의 MDC-Android 구성요소
- AppBarLayout
- MaterialCardView
필요한 항목
- Android 개발에 관한 기본 지식
- Android 스튜디오(아직 다운로드하지 않은 경우 여기에서 다운로드)
- Android Emulator 또는 기기(Android 스튜디오를 통해 사용 가능)
- 샘플 코드(다음 단계 참고)
귀하의 Android 앱 빌드 경험 수준을 평가해 주세요.
2. 개발 환경 설정
MDC-101에서 계속 진행
MDC-101을 완료했다면 이 Codelab을 위한 코드가 준비된 것입니다. 3단계(상단 앱 바 추가)로 건너뛰어도 됩니다.
처음부터 새로 시작
시작 Codelab 앱 다운로드
시작 앱은 material-components-android-codelabs-102-starter/java
디렉터리에 있습니다. 시작하기 전에 해당 디렉터리로 cd
이동해야 합니다.
...또는 GitHub에서 클론
이 Codelab을 GitHub에서 클론하려면 다음 명령어를 실행하세요.
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 102-starter
Android 스튜디오에서 시작 코드 로드
- 설정 마법사가 완료되고 Welcome to Android Studio 창이 표시되면 Open an existing Android Studio project를 클릭합니다. 샘플 코드를 설치한 디렉터리로 이동하여 java -> Shrine을 선택하거나 컴퓨터에서 shrine을 검색하여 Shrine 프로젝트를 엽니다.
- Android 스튜디오 창 하단의 활동 표시기에 나타나는 것처럼 Android 스튜디오가 프로젝트를 빌드하고 동기화할 때까지 잠시 기다립니다.
- 이 시점에서 Android 스튜디오에 아래와 같은 빌드 오류가 발생할 수 있습니다. Android SDK나 빌드 도구가 누락되었기 때문입니다. Android 스튜디오의 안내를 따라 이러한 항목을 설치/업데이트하고 프로젝트를 동기화합니다.
프로젝트 종속 항목 추가
프로젝트에는 MDC Android 지원 라이브러리의 종속 항목이 필요합니다. 다운로드한 샘플 코드에는 이 종속 항목이 이미 나열되어 있지만, 다음 단계를 수행하여 확인하는 것이 좋습니다.
app
모듈의build.gradle
파일로 이동하여dependencies
블록에 MDC Android의 종속 항목이 포함되어 있는지 확인합니다.
api 'com.google.android.material:material:1.1.0-alpha06'
- (선택사항) 필요한 경우
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' }
시작 앱 실행
|
완료되었습니다. MDC-101 Codelab의 Shrine 로그인 페이지가 표시됩니다.
이제 로그인 화면이 제대로 표시되므로 앱을 제품으로 채워보겠습니다.
3. 상단 앱 바 추가
로그인 페이지가 닫히면 '축하합니다'라는 화면과 함께 홈 화면이 표시됩니다. 훌륭합니다. 하지만 이제 사용자는 해야 할 작업이 없거나 앱에서 사용자의 위치를 파악할 수 없습니다. 이를 돕기 위해 탐색을 추가해 보겠습니다.
머티리얼 디자인은 높은 수준의 사용성을 보장하는 탐색 패턴을 제공합니다. 가장 눈에 띄는 탐색 구성요소 중 하나는 상단 앱 바입니다.
탐색 기능을 제공하고 사용자가 다른 작업에 빠르게 액세스할 수 있도록 상단 앱 바를 추가해보겠습니다.
AppBar 위젯 추가
shr_product_grid_fragment.xml
에서 '완료'가 포함된 <LinearLayout>
태그를 삭제합니다. TextView
를 다음으로 바꿉니다.
shr_product_grid_fragment.xml
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
shr_product_grid_fragment.xml
는 다음과 같이 표시됩니다.
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
대다수 앱 바에는 제목 옆에 버튼이 있습니다. 메뉴 아이콘을 추가해 보겠습니다.
탐색 아이콘 추가하기
계속 shr_product_grid_fragment.xml
에서 레이아웃에 방금 추가한 Toolbar
XML 구성요소에 다음을 추가합니다.
shr_product_grid_fragment.xml
app:navigationIcon="@drawable/shr_menu"
shr_product_grid_fragment.xml
은 다음과 같이 표시됩니다.
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
</FrameLayout>
작업 버튼 추가 및 상단 앱 바 스타일 지정
앱 바의 끝에 버튼을 추가할 수도 있습니다. Android에서는 이를 작업 버튼이라고 합니다.
상단 앱 바의 스타일을 지정하고 프로그래매틱 방식으로 메뉴에 작업 버튼을 추가합니다.
먼저 툴바를 설정하는 메서드를 만들어 보겠습니다. 메서드는 id
를 사용하여 툴바 참조를 가져오고 getActivity()
를 사용하여 활동 참조도 가져와야 합니다. 활동이 null이 아니면 setSupportActionBar
를 사용하여 Toolbar
를 ActionBar
로 사용하도록 설정합니다.
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);
}
}
다음으로 방금 추가한 setUpToolbar
메서드 바로 아래에서 onCreateOptionsMenu
를 재정의하여 shr_toolbar_menu.xml
의 콘텐츠를 툴바에 확장합니다.
ProductGridFragment.java
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
이제 다음을 사용하여 onCreateView()
메서드의 콘텐츠에 추가한 setUpToolbar
메서드 호출을 추가합니다.
ProductGridFragment.java
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
return view;
}
마지막으로 ProductGridFragment.java
에 onCreate()
메서드를 추가합니다. 메서드 본문에서 setHasOptionMenu
의 매개변수를 true
로 설정합니다.
메서드는 다음과 같이 표시됩니다.
ProductGridFragment.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
위의 코드는 XML 레이아웃의 앱 바를 이 활동의 작업 모음으로 설정합니다. 콜백 onCreateOptionsMenu
는 메뉴로 사용할 항목을 활동에 알려줍니다. 이 경우 R.menu.shr_toolbar_menu
의 메뉴 항목이 앱 바에 배치됩니다.
메뉴 파일에는 '검색' 및 '필터'의 두 항목이 포함되어 있습니다.
shr_toolbar_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/shr_search"
android:title="@string/shr_search_title"
app:showAsAction="always" />
<item
android:id="@+id/filter"
android:icon="@drawable/shr_filter"
android:title="@string/shr_filter_title"
app:showAsAction="always" />
</menu>
이렇게 변경하면 ProductGridFragment.java
파일이 다음과 같이 표시됩니다.
ProductGridFragment.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
public class ProductGridFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
return view;
}
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
}
빌드하고 실행합니다. 홈 화면이 다음과 같이 표시됩니다.
이제 툴바에 탐색 아이콘, 제목, 오른쪽에 두 개의 작업 아이콘이 있습니다. 또한 툴바는 콘텐츠와 다른 레이어에 있음을 나타내는 엷은 그림자를 사용하여 고도를 표시합니다.
4. 카드 추가
앱에 구조가 생겼으니 이제 콘텐츠를 카드에 배치하여 정리해 보겠습니다.
카드 추가하기
이제 상단 앱 바 아래에 카드 하나를 추가해보겠습니다. 카드에는 이미지 영역, 제목, 보조 텍스트 라벨이 있어야 합니다.
shr_product_grid_fragment.xml
에서 AppBarLayout
아래에 다음을 추가합니다.
shr_product_grid_fragment.xml
<com.google.android.material.card.MaterialCardView
android:layout_width="160dp"
android:layout_height="180dp"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="70dp"
app:cardBackgroundColor="?attr/colorPrimaryDark"
app:cardCornerRadius="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#FFFFFF"
android:orientation="vertical"
android:padding="8dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="2dp"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
빌드 및 실행:
이 미리보기에서는 카드가 화면 왼쪽 가장자리에서 삽입되어 있으며 모서리가 둥글고 그림자 (카드의 고도를 나타냄)가 있음을 알 수 있습니다. 전체 영역을 '컨테이너'라고 합니다. 컨테이너 자체를 제외하고 컨테이너 내의 모든 요소는 선택사항입니다.
헤더 텍스트, 썸네일 또는 아바타, 부제목 텍스트, 구분선, 버튼 및 아이콘과 같은 요소를 컨테이너에 추가할 수 있습니다. 예를 들어 방금 만든 카드에는 LinearLayout
에 TextView
가 두 개(하나는 제목용, 하나는 보조 텍스트용) 포함되어 있으며 카드 하단에 정렬되어 있습니다.
카드는 보통 다른 카드와 함께 컬렉션으로 표시됩니다. 이 Codelab의 다음 섹션에서는 카드를 그리드에 컬렉션으로 배치합니다.
5. 카드 그리드 만들기
한 화면에 여러 개의 카드가 표시되면 하나 이상의 컬렉션으로 그룹화됩니다. 그리드의 카드는 동일 평면상에 있습니다. 즉, 카드는 서로 동일한 휴면 고도를 공유합니다. 단, 카드를 선택하거나 드래그하는 경우는 예외이지만 이 Codelab에서는 다루지 않습니다.
카드 그리드 설정
제공된 shr_product_card.xml
파일을 살펴보세요.
shr_product_card.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="@android:color/white"
app:cardElevation="2dp"
app:cardPreventCornerOverlap="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/product_image"
android:layout_width="match_parent"
android:layout_height="@dimen/shr_product_card_image_height"
android:background="?attr/colorPrimaryDark"
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/product_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_title"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:id="@+id/product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shr_product_description"
android:textAppearance="?attr/textAppearanceBody2" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
이 카드 레이아웃에는 이미지가 포함된 카드(여기서는 URL의 이미지를 포함할 수 있는 NetworkImageView
)와 TextViews
2개가 포함되어 있습니다.
다음으로 제공된 ProductCardRecyclerViewAdapter
를 살펴보세요. ProductGridFragment
와 동일한 패키지에 있습니다.
ProductCardRecyclerViewAdapter.java
package com.google.codelabs.mdc.java.shrine;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.google.codelabs.mdc.java.shrine.network.ImageRequester;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;
import java.util.List;
/**
* Adapter used to show a simple grid of products.
*/
public class ProductCardRecyclerViewAdapter extends RecyclerView.Adapter<ProductCardViewHolder> {
private List<ProductEntry> productList;
private ImageRequester imageRequester;
ProductCardRecyclerViewAdapter(List<ProductEntry> productList) {
this.productList = productList;
imageRequester = ImageRequester.getInstance();
}
@NonNull
@Override
public ProductCardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.shr_product_card, parent, false);
return new ProductCardViewHolder(layoutView);
}
@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
// TODO: Put ViewHolder binding code here in MDC-102
}
@Override
public int getItemCount() {
return productList.size();
}
}
위의 어댑터 클래스는 그리드의 콘텐츠를 관리합니다. 각 뷰가 주어진 콘텐츠로 무엇을 해야 하는지 결정하기 위해 곧 onBindViewHolder()
의 코드를 작성할 것입니다.
같은 패키지에서 ProductCardViewHolder
를 확인할 수도 있습니다. 이 클래스는 나중에 수정할 수 있도록 카드 레이아웃에 영향을 미치는 뷰를 저장합니다.
ProductCardViewHolder.java
package com.google.codelabs.mdc.java.shrine;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
public class ProductCardViewHolder extends RecyclerView.ViewHolder {
public ProductCardViewHolder(@NonNull View itemView) {
super(itemView);
// TODO: Find and store views from itemView
}
}
그리드를 설정하려면 먼저 shr_product_grid_fragment.xml
에서 자리표시자 MaterialCardView
를 삭제해야 합니다. 다음으로 카드 그리드를 나타내는 구성요소를 추가해야 합니다. 이 경우 AppBarLayout
XML 구성요소 아래의 shr_product_grid_fragment.xml
에 RecyclerView 구성요소를 추가합니다.
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:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
shr_product_grid_fragment.xml
는 다음과 같이 표시됩니다.
shr_product_grid_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ProductGridFragment">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/app_bar"
style="@style/Widget.Shrine.Toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:navigationIcon="@drawable/shr_menu"
app:title="@string/shr_app_name" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp"
android:background="@color/productGridBackgroundColor"
android:paddingStart="@dimen/shr_product_grid_spacing"
android:paddingEnd="@dimen/shr_product_grid_spacing"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.core.widget.NestedScrollView>
</FrameLayout>
마지막으로 onCreateView()
에서 setUpToolbar(view)
를 호출한 후와 return
문 앞에 RecyclerView
초기화 코드를 ProductGridFragment.java
에 추가합니다.
ProductGridFragment.java
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
setUpToolbar(view);
// Set up the RecyclerView
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(getResources()));
recyclerView.setAdapter(adapter);
int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));
return view;
}
위의 코드 스니펫에는 RecyclerView
를 설정하는 데 필요한 초기화 단계가 포함되어 있습니다. 여기에는 RecyclerView
의 레이아웃 관리자 설정, RecyclerView
의 어댑터 초기화 및 설정이 포함됩니다.
이제 ProductGridFragment.java
파일이 다음과 같이 표시됩니다.
ProductGridFragment.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toolbar;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import com.google.codelabs.mdc.java.shrine.network.ProductEntry;
public class ProductGridFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment with the ProductGrid theme
View view = inflater.inflate(R.layout.shr_product_grid_fragment, container, false);
// Set up the toolbar
setUpToolbar(view);
// Set up the RecyclerView
RecyclerView recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2, GridLayoutManager.VERTICAL, false));
ProductCardRecyclerViewAdapter adapter = new ProductCardRecyclerViewAdapter(
ProductEntry.initProductEntryList(getResources()));
recyclerView.setAdapter(adapter);
int largePadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing);
int smallPadding = getResources().getDimensionPixelSize(R.dimen.shr_product_grid_spacing_small);
recyclerView.addItemDecoration(new ProductGridItemDecoration(largePadding, smallPadding));
return view;
}
private void setUpToolbar(View view) {
Toolbar toolbar = view.findViewById(R.id.app_bar);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
activity.setSupportActionBar(toolbar);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
menuInflater.inflate(R.menu.shr_toolbar_menu, menu);
super.onCreateOptionsMenu(menu, menuInflater);
}
}
빌드하고 실행합니다.
이제 카드가 표시됩니다. 아직 아무것도 표시되지 않으므로 제품 데이터를 추가해 보겠습니다.
이미지 및 텍스트 추가하기
각 카드에 이미지, 제품 이름, 가격을 추가합니다. ViewHolder
추상화는 각 카드의 뷰를 보유합니다. ViewHolder
에서 다음과 같이 세 개의 뷰를 추가합니다.
ProductCardViewHolder.java
package com.google.codelabs.mdc.java.shrine;
import androidx.recyclerview.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.volley.toolbox.NetworkImageView;
public class ProductCardViewHolder extends RecyclerView.ViewHolder {
public NetworkImageView productImage;
public TextView productTitle;
public TextView productPrice;
public ProductCardViewHolder(@NonNull View itemView) {
super(itemView);
productImage = itemView.findViewById(R.id.product_image);
productTitle = itemView.findViewById(R.id.product_title);
productPrice = itemView.findViewById(R.id.product_price);
}
}
RecyclerView
의 어댑터에서 ViewHolder,
에서 onBindViewHolder()
메서드를 업데이트하여 각 뷰에 정보를 설정합니다.
ProductCardRecyclerViewAdapter.java
@Override
public void onBindViewHolder(@NonNull ProductCardViewHolder holder, int position) {
if (productList != null && position < productList.size()) {
ProductEntry product = productList.get(position);
holder.productTitle.setText(product.title);
holder.productPrice.setText(product.price);
imageRequester.setImageFromUrl(holder.productImage, product.url);
}
}
위 코드는 ViewHolder
를 사용하여 RecyclerView
의 어댑터에 각 카드로 무엇을 해야 하는지 알려줍니다.
여기서는 각 ViewHolder
의 TextView
에 텍스트 데이터를 설정하고 ImageRequester
를 호출하여 URL에서 이미지를 가져옵니다. ImageRequester
는 편의를 위해 제공된 클래스이며 Volley
라이브러리를 사용합니다. 이 Codelab의 범위를 벗어나는 주제이지만 직접 코드를 탐색해도 됩니다.
빌드 및 실행:
이제 제품이 앱에 표시됩니다.
6. 요약
앱에는 사용자를 로그인 화면에서 제품을 볼 수 있는 홈 화면으로 안내하는 기본적인 흐름이 있습니다. 코드 몇 줄만으로 제목과 버튼 3개가 있는 상단 앱 바와 앱 콘텐츠를 표시하는 카드 그리드를 추가했습니다. 이제 홈 화면이 기본적인 구조와 실행 가능한 콘텐츠로 간단하고 기능적입니다.
다음 단계
이제 상단 앱 바와 카드, 텍스트 필드, 버튼을 사용하여 MDC-Android 라이브러리의 네 가지 핵심 Material Design 구성요소를 사용했습니다. MDC-Android 카탈로그 MDC Android의 구성요소에서 더 많은 구성요소를 살펴볼 수 있습니다.
앱이 완전히 작동하지만 아직 특정 브랜드를 표현하지는 않습니다. MDC-103: 색상, 모양, 고도, 유형을 사용한 머티리얼 디자인 테마에서 이러한 구성요소의 스타일을 맞춤설정하여 생동감 있고 현대적인 브랜드를 표현합니다.