۱. مقدمه
کامپوننتهای متریال (MDC) به توسعهدهندگان در پیادهسازی طراحی متریال کمک میکنند. MDC که توسط تیمی از مهندسان و طراحان UX در گوگل ایجاد شده است، دهها کامپوننت رابط کاربری زیبا و کاربردی را ارائه میدهد و برای اندروید، iOS، وب و Flutter.material.io/develop در دسترس است. |
طراحی متریال و کامپوننتهای متریال برای اندروید چیستند؟
طراحی متریال سیستمی برای ساخت محصولات دیجیتال جسورانه و زیبا است. با متحد کردن سبک، برندسازی، تعامل و حرکت تحت مجموعهای از اصول و اجزای سازگار، تیمهای محصول میتوانند به بزرگترین پتانسیل طراحی خود دست یابند.
برای برنامههای اندروید، کامپوننتهای متریال برای اندروید ( MDC Android ) طراحی و مهندسی را با کتابخانهای از کامپوننتها برای ایجاد سازگاری در سراسر برنامه شما متحد میکند. با تکامل سیستم طراحی متریال، این کامپوننتها بهروزرسانی میشوند تا پیادهسازی پیکسلی بینقص و مطابق با استانداردهای توسعه front-end گوگل تضمین شود. MDC همچنین برای وب، iOS و Flutter در دسترس است.
در این آزمایشگاه کد، شما با استفاده از چندین کامپوننت اندروید MDC یک صفحه ورود خواهید ساخت.
آنچه خواهید ساخت
این آزمایشگاه کد، اولین از ۴ آزمایشگاه کد است که شما را در ساخت برنامهای به نام Shrine ، یک برنامه اندروید تجارت الکترونیک که لباس و لوازم خانگی میفروشد، راهنمایی میکند. این آزمایشگاه نشان میدهد که چگونه میتوانید با استفاده از MDC-Android، اجزا را برای انعکاس هر برند یا سبکی سفارشی کنید.
در این آزمایشگاه کد، شما یک صفحه ورود برای Shrine خواهید ساخت که شامل موارد زیر است:
- دو فیلد متنی، یکی برای وارد کردن نام کاربری و دیگری برای وارد کردن رمز عبور
- دو دکمه، یکی برای «لغو» و دیگری برای «بعدی»
- نام برنامه (معبد)
- تصویری از لوگوی Shrine

اجزای اندروید MDC در این آزمایشگاه کد
- فیلد متنی
- دکمه
آنچه نیاز دارید
- دانش پایه در توسعه اندروید
- اندروید استودیو (اگر ندارید، از اینجا دانلود کنید)
- یک شبیهساز یا دستگاه اندروید (از طریق اندروید استودیو قابل دسترسی است)
- کد نمونه (به مرحله بعدی مراجعه کنید)
سطح تجربه خود در ساخت برنامههای اندروید را چگونه ارزیابی میکنید؟
۲. محیط توسعه خود را تنظیم کنید
راه اندازی اندروید استودیو
وقتی اندروید استودیو را باز میکنید، باید پنجرهای با عنوان "به اندروید استودیو خوش آمدید" نمایش داده شود. با این حال، اگر این اولین بار است که اندروید استودیو را اجرا میکنید، مراحل نصب اندروید استودیو را با مقادیر پیشفرض طی کنید. این مرحله میتواند چند دقیقه طول بکشد تا فایلهای لازم دانلود و نصب شوند، بنابراین میتوانید این مرحله را در پسزمینه اجرا کنید و بخش بعدی را انجام دهید.
اپلیکیشن استارتر codelab را دانلود کنید
برنامهی آغازین در دایرکتوری material-components-android-codelabs-101-starter/java قرار دارد.
... یا آن را از گیتهاب کلون کنید
برای کپی کردن این codelab از گیتهاب، دستورات زیر را اجرا کنید:
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 101-starter
کد شروع را در اندروید استودیو بارگذاری کنید
- پس از اتمام مراحل نصب و نمایش پنجره Welcome to Android Studio ، روی Open an existing Android Studio project کلیک کنید. به پوشهای که کد نمونه را در آن نصب کردهاید بروید و java -> shrine را انتخاب کنید (یا در رایانه خود عبارت shrine را جستجو کنید) تا پروژه Shrine باز شود.
- لحظهای صبر کنید تا اندروید استودیو پروژه را بسازد و همگامسازی کند، همانطور که توسط نشانگرهای فعالیت در پایین پنجره اندروید استودیو نشان داده شده است.
- در این مرحله، ممکن است اندروید استودیو به دلیل فقدان SDK اندروید یا ابزارهای ساخت، مانند آنچه در زیر نشان داده شده است، برخی خطاهای ساخت را ایجاد کند. برای نصب/بهروزرسانی این موارد و همگامسازی پروژه خود، دستورالعملهای موجود در اندروید استودیو را دنبال کنید.
اضافه کردن وابستگیهای پروژه
این پروژه به یک وابستگی (dependency) در کتابخانه پشتیبانی اندروید MDC نیاز دارد. کد نمونهای که دانلود کردهاید باید از قبل این وابستگی را داشته باشد، اما برای اطمینان، انجام مراحل زیر توصیه میشود.
- به فایل
build.gradleماژولappبروید و مطمئن شوید که بلوک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'
}
برنامه شروع کننده را اجرا کنید
|
موفقیت! کد آغازین برای صفحه ورود به Shrine باید در شبیهساز شما اجرا شود. باید نام "Shrine" و لوگوی Shrine را درست در زیر آن ببینید.

بیایید نگاهی به کد بیندازیم. ما در کد نمونه خود یک چارچوب ناوبری ساده Fragment برای نمایش Fragmentها و پیمایش بین Fragmentها ارائه دادهایم.
MainActivity.java در دایرکتوری shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.java.shrine باز کنید. این فایل باید شامل موارد زیر باشد:
MainActivity.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity implements NavigationHost {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shr_main_activity);
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.container, new LoginFragment())
.commit();
}
}
/**
* Navigate to the given fragment.
*
* @param fragment Fragment to navigate to.
* @param addToBackstack Whether or not the current fragment should be added to the backstack.
*/
@Override
public void navigateTo(Fragment fragment, boolean addToBackstack) {
FragmentTransaction transaction =
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment);
if (addToBackstack) {
transaction.addToBackStack(null);
}
transaction.commit();
}
}
این فعالیت، فایل طرحبندی R.layout.shr_main_activity را که در shr_main_activity.xml تعریف شده است، نمایش میدهد.
میتوانید ببینید که در onCreate(), MainActivity.java یک تراکنش Fragment را برای نمایش LoginFragment آغاز میکند LoginFragment. این چیزی است که ما برای این آزمایشگاه کد اصلاح خواهیم کرد. این اکتیویتی همچنین یک متد navigateTo(Fragment) را پیادهسازی میکند که در NavigationHost تعریف شده است و به هر قطعهای اجازه میدهد تا به قطعهی دیگری هدایت شود.
برای باز کردن فایل طرحبندی، در فایل activity، کلیدهای Command + Click (یا Control + Click ) را فشار دهید تا فایل طرحبندی shr_main_activity باز شود، یا از طریق app -> res -> layout -> shr_main_activity.xml به فایل طرحبندی بروید.
shr_main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" />
در اینجا، یک <FrameLayout> ساده میبینیم که به عنوان یک ظرف برای هر قطعهای که activity نمایش میدهد عمل میکند. بیایید LoginFragment.java را باز کنیم.
ورودFragment.java
package com.google.codelabs.mdc.java.shrine;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
/**
* Fragment representing the login screen for Shrine.
*/
public class LoginFragment extends Fragment {
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.shr_login_fragment, container, false);
// Snippet from "Navigate to the next Fragment" section goes here.
return view;
}
// "isPasswordValid" from "Navigate to the next Fragment" section method goes here
}
LoginFragment فایل طرحبندی shr_login_fragment را inflate کرده و آن را در onCreateView() نمایش میدهد. بیایید نگاهی به فایل طرحبندی shr_login_fragment.xml بیندازیم تا ببینیم صفحه ورود به سیستم چگونه به نظر میرسد.
shr_login_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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"
android:background="@color/loginPageBackgroundColor"
tools:context=".LoginFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
android:padding="24dp"
android:paddingTop="16dp">
<ImageView
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="48dp"
android:layout_marginBottom="16dp"
app:srcCompat="@drawable/shr_logo" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="132dp"
android:text="@string/shr_app_name"
android:textAllCaps="true"
android:textSize="16sp" />
<!-- Snippet from "Add text fields" section goes here. -->
<!-- Snippet from "Add buttons" section goes here. -->
</LinearLayout>
</ScrollView>
در اینجا، میتوانیم یک <LinearLayout> با یک <ImageView> در بالا ببینیم که نشاندهندهی لوگوی «Shrine» است.
پس از آن، یک تگ <TextView> وجود دارد که نشاندهنده برچسب "SHRINE" است. متن این برچسب یک منبع رشتهای با نام @string/shr_app_name است. اگر نام منبع رشتهای را با کلیدهای Command + Click (یا Control + Click ) فشار دهید، یا app -> res -> values -> strings.xml را باز کنید، میتوانید فایل strings.xml را که منابع رشتهای در آن تعریف شدهاند، مشاهده کنید. وقتی منابع رشتهای بیشتری در آینده اضافه شوند، در اینجا تعریف خواهند شد. هر منبعی در این فایل باید یک پیشوند shr_ داشته باشد تا نشان دهد که بخشی از برنامه Shrine است.
حالا که با کد اولیه آشنا شدید، بیایید اولین کامپوننت خود را پیادهسازی کنیم.
۳. فیلدهای متنی اضافه کنید
برای شروع، دو فیلد متنی به صفحه ورود خود اضافه خواهیم کرد تا افراد بتوانند نام کاربری و رمز عبور خود را وارد کنند. ما از کامپوننت MDC Text Field استفاده خواهیم کرد که شامل قابلیتهای داخلی نمایش برچسب شناور و پیامهای خطا است.

XML را اضافه کنید
در shr_login_fragment.xml ، دو عنصر TextInputLayout با یک عنصر فرزند TextInputEditText درون <LinearLayout> و زیر برچسب "SHRINE" یعنی <TextView> اضافه کنید:
shr_login_fragment.xml
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:hint="@string/shr_hint_username">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/password_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:hint="@string/shr_hint_password">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
قطعه کد بالا دو فیلد متنی را نشان میدهد که هر کدام شامل یک عنصر <TextInputLayout> و یک فرزند <TextInputEditText> هستند. متن راهنما برای هر فیلد متنی در ویژگی android:hint مشخص شده است.
ما دو منبع رشتهای جدید برای فیلد متن اضافه کردهایم - @string/shr_hint_username و @string/shr_hint_password . برای مشاهده این منابع رشتهای، strings.xml را باز کنید.
رشتهها.xml
...
<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>
...
اعتبارسنجی ورودی را اضافه کنید
کامپوننتهای TextInputLayout قابلیت بازخورد خطا را به صورت داخلی ارائه میدهند.
برای نمایش بازخورد خطا، تغییرات زیر را در shr_login_fragment.xml اعمال کنید:
- ویژگی
app:errorEnabledرا در عنصر PasswordTextInputLayoutروی true تنظیم کنید. این کار باعث میشود که برای پیام خطا در زیر فیلد متن، حاشیه اضافی اضافه شود. - ویژگی
android:inputTypeدر عنصر PasswordTextInputEditTextبرابر با "textPassword" قرار دهید. این کار متن ورودی را در فیلد رمز عبور پنهان میکند.
با این تغییرات، فیلدهای متنی در shr_login_fragment.xml باید به شکل زیر باشند:
shr_login_fragment.xml
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:hint="@string/shr_hint_username">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/password_text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:hint="@string/shr_hint_password"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>
حالا برنامه را اجرا کنید. باید صفحهای با دو فیلد متنی برای «نام کاربری» و «رمز عبور» ببینید!
انیمیشن برچسب شناور را ببینید:

۴. دکمهها را اضافه کنید
در مرحله بعد، دو دکمه به صفحه ورود خود اضافه خواهیم کرد: «لغو» و «بعدی». ما از کامپوننت دکمه MDC استفاده خواهیم کرد که دارای جلوه موجی جوهر Material Design است.

XML را اضافه کنید
در shr_login_fragment.xml ، یک <RelativeLayout> به <LinearLayout> ، زیر عناصر TextInputLayout اضافه کنید. سپس دو عنصر <MaterialButton> را به <RelativeLayout> اضافه کنید.
فایل XML حاصل باید به شکل زیر باشد:
shr_login_fragment.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/next_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:text="@string/shr_button_next" />
<com.google.android.material.button.MaterialButton
android:id="@+id/cancel_button"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:layout_marginRight="12dp"
android:layout_toStartOf="@id/next_button"
android:layout_toLeftOf="@id/next_button"
android:text="@string/shr_button_cancel" />
</RelativeLayout>
همین! وقتی برنامه را اجرا میکنید، با لمس هر دکمه، موجی از جوهر نمایش داده میشود.

۵. رفتن به قطعه بعدی
در نهایت، مقداری کد جاوا به LoginFragment.java اضافه خواهیم کرد تا دکمه "NEXT" را به یک fragment دیگر متصل کنیم. متوجه خواهید شد که به هر یک از کامپوننتهایی که به layout خود اضافه کردیم، یک id ) اختصاص داده شده است. ما از این id برای ارجاع به کامپوننتها در کد خود و اضافه کردن برخی امکانات بررسی خطا و ناوبری استفاده خواهیم کرد.
بیایید یک متد خصوصی از نوع بولی به نام isPasswordValid در LoginFragment.java در زیر onCreateView() اضافه کنیم، با منطقی که تعیین کند رمز عبور معتبر است یا خیر. برای اهداف این نسخه آزمایشی، فقط مطمئن میشویم که رمز عبور حداقل ۸ کاراکتر داشته باشد:
ورودFragment.java
/*
In reality, this will have more complex logic including, but not limited to, actual
authentication of the username and password.
*/
private boolean isPasswordValid(@Nullable Editable text) {
return text != null && text.length() >= 8;
}
در مرحله بعد، یک شنونده کلیک به دکمه "Next" اضافه کنید که خطا را بر اساس متد isPasswordValid() که تازه ایجاد کردهایم، تنظیم و پاک میکند. در onCreateView() ، این شنونده کلیک باید بین خط inflater و خط return view قرار گیرد.
در مرحله بعد، بیایید یک شنونده کلید به TextInputEditText رمز عبور اضافه کنیم تا به رویدادهای کلیدی که خطا را برطرف میکنند گوش دهد. این شنونده همچنین باید isPasswordValid() برای بررسی معتبر بودن یا نبودن رمز عبور استفاده کند. میتوانید این را مستقیماً زیر شنونده کلیک در onCreateView() اضافه کنید.
متد onCreateView() شما اکنون باید چیزی شبیه به این باشد:
ورودFragment.java
@Override
public View onCreateView(
@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.shr_login_fragment, container, false);
final TextInputLayout passwordTextInput = view.findViewById(R.id.password_text_input);
final TextInputEditText passwordEditText = view.findViewById(R.id.password_edit_text);
MaterialButton nextButton = view.findViewById(R.id.next_button);
// Set an error if the password is less than 8 characters.
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(getString(R.string.shr_error_password));
} else {
passwordTextInput.setError(null); // Clear the error
}
}
});
// Clear the error once more than 8 characters are typed.
passwordEditText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(null); //Clear the error
}
return false;
}
});
return view;
}
حالا میتوانیم به یک قطعه کد دیگر برویم. OnClickListener در onCreateView() بهروزرسانی کنید تا وقتی اعتبارسنجی خطا با موفقیت انجام شد، به قطعه کد دیگری برویم. میتوانید این کار را با اضافه کردن خط زیر برای رفتن به ProductGridFragment به حالت else از شنونده کلیک انجام دهید:
ورودFragment.java
...
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
...
شنونده کلیک شما اکنون باید به شکل زیر باشد:
ورودFragment.java
...
MaterialButton nextButton = view.findViewById(R.id.next_button);
// Set an error if the password is less than 8 characters.
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPasswordValid(passwordEditText.getText())) {
passwordTextInput.setError(getString(R.string.shr_error_password));
} else {
passwordTextInput.setError(null); // Clear the error
((NavigationHost) getActivity()).navigateTo(new ProductGridFragment(), false); // Navigate to the next Fragment
}
}
});
...
این خط کد جدید، متد navigateTo() از MainActivity فراخوانی میکند تا به یک فرگمنت جدید - ProductGridFragment - هدایت شود. در حال حاضر، این یک صفحه خالی است که در MDC-102 روی آن کار خواهید کرد.
حالا، برنامه را بسازید. ادامه دهید و دکمه Next را بزنید.
موفق شدی! این صفحه، نقطه شروع آزمایشگاه کد بعدی ما خواهد بود که در MDC-102 روی آن کار خواهی کرد.
۶. همه چیز انجام شد
کتابخانه Material Components for Android با استفاده از نشانهگذاری XML پایه و حدود ۳۰ خط کد جاوا، به شما کمک کرده است تا یک صفحه ورود زیبا ایجاد کنید که با دستورالعملهای طراحی متریال مطابقت داشته باشد و همچنین در همه دستگاهها به طور یکسان ظاهر و رفتار کند.
مراحل بعدی
فیلد متنی و دکمه دو کامپوننت اصلی در کتابخانه اندروید MDC هستند، اما کامپوننتهای بسیار بیشتری وجود دارد! میتوانید بقیه کامپوننتها را در MDC Android بررسی کنید. همچنین، میتوانید به MDC 102: ساختار و چیدمان طراحی متریال مراجعه کنید تا در مورد نوار بالای برنامه، نمای کارت و چیدمان شبکهای اطلاعات کسب کنید. از تلاش شما برای استفاده از کامپوننتهای متریال متشکریم. امیدواریم از این آزمایشگاه کد لذت برده باشید!