1. مقدمة
تساعد مكونات Material Design (MDC) المطوّرين في تنفيذ أسلوب Material Design. تم إنشاء MDC من قِبل فريق من المهندسين ومصممي تجربة المستخدم في Google، ويضمّ عشرات مكوّنات واجهة المستخدم الجميلة والوظيفية، وهو متاح لنظام التشغيل Android وiOS والويب وFlutter.material.io/develop |
ما هو التصميم المتعدد الأبعاد والمكوّنات المادية لنظام Android؟
التصميم المتعدد الأبعاد هو نظام لتصميم منتجات رقمية جريئة وجميلة. من خلال توحيد الأسلوب والعلامات التجارية والتفاعل والحركة في ظل مجموعة متسقة من المبادئ والمكونات، يمكن لفرق المنتجات تحقيق أكبر إمكانات التصميم.
بالنسبة إلى تطبيقات Android، تجمع مكونات Material Design لنظام التشغيل Android (MDC Android) بين التصميم والهندسة مع مكتبة من المكوّنات لإنشاء اتساق في تطبيقك. ومع تطور نظام Material Design، يتم تعديل هذه المكوّنات لضمان التنفيذ المتسق بدقة على مستوى البكسل والالتزام بمعايير تطوير الواجهة الأمامية من Google. تتوفّر حزمة MDC أيضًا على الويب وiOS وFlutter.
في هذا الدرس التطبيقي، ستُنشئ صفحة تسجيل دخول باستخدام العديد من مكونات MDC Android.
التطبيق الذي ستصممه
هذا الدرس التطبيقي هو الأول من بين 4 دروس تطبيقية حول الترميز سترشدك خلال إنشاء تطبيق باسم Shrine، وهو تطبيق للتجارة الإلكترونية على Android يبيع الملابس والسلع المنزلية. سيوضح لك هذا الدليل كيفية تخصيص المكوّنات لتعكس أي علامة تجارية أو نمط باستخدام MDC Android.
في هذا الدرس التطبيقي حول الترميز، ستنشئ صفحة تسجيل دخول إلى Shrine تحتوي على:
- حقلَا نصّيَّين، أحدهما لإدخال اسم مستخدم والآخر لكلمة مرور
- زران، أحدهما لـ "إلغاء" والآخر لـ "التالي"
- اسم التطبيق (Shrine)
- صورة شعار Shrine
مكوّنات MDC لنظام التشغيل Android في هذا الدرس التطبيقي حول الترميز
- حقل نصي
- زرّ
المتطلبات
- معرفة أساسية بتطوير تطبيقات Android
- استوديو Android (يمكنك تنزيله من هنا إذا لم يكن متوفّرًا لديك)
- محاكي أو جهاز Android (متاح من خلال "استوديو Android")
- نموذج التعليمات البرمجية (راجِع الخطوة التالية)
ما هو تقييمك لمستوى خبرتك في إنشاء تطبيقات Android؟
2. إعداد بيئة التطوير
بدء استخدام "استوديو Android"
عند فتح استوديو Android، من المفترض أن تظهر لك نافذة بعنوان "مرحبًا بك في استوديو Android". ومع ذلك، إذا كانت هذه هي المرة الأولى التي تشغِّل فيها "استوديو Android"، يمكنك اتّباع خطوات معالج إعداد "استوديو Android" باستخدام القيم التلقائية. قد تستغرق هذه الخطوة عدة دقائق لتنزيل الملفات الضرورية وتثبيتها، لذا يمكنك ترك هذه الخطوة قيد التشغيل في الخلفية أثناء تنفيذ القسم التالي.
تنزيل تطبيق "الدرس التطبيقي حول الترميز" للمبتدئين
يتوفّر تطبيق إجراء التفعيل ضمن دليل material-components-android-codelabs-101-starter/kotlin
.
...أو استنساخها من GitHub
لنسخ هذا الدليل التعليمي من GitHub، شغِّل الأوامر التالية:
git clone https://github.com/material-components/material-components-android-codelabs cd material-components-android-codelabs/ git checkout 101-starter
تحميل رمز إجراء التفعيل في "استوديو Android"
- بعد انتهاء معالج الإعداد وظهور نافذة مرحبًا بك في "استوديو Android"، انقر على فتح مشروع حالي في "استوديو Android". انتقِل إلى الدليل الذي ثبَّت فيه نموذج الرمز البرمجي، واختَر kotlin -> shrine (أو ابحث في جهاز الكمبيوتر عن shrine) لفتح مشروع Shipping.
- انتظِر قليلاً إلى أن ينشئ "استوديو Android" المشروع ويزامنه، كما هو موضّح في مؤشرات النشاط في أسفل نافذة "استوديو Android".
- في هذه المرحلة، قد يعرض "استوديو Android" بعض أخطاء الإنشاء بسبب عدم توفّر حزمة تطوير البرامج (SDK) لنظام التشغيل Android أو أدوات الإنشاء، مثل الخطأ الموضّح أدناه. اتّبِع التعليمات الواردة في "استوديو Android" لتثبيت هذه الأدوات أو تحديثها ومزامنة مشروعك.
إضافة تبعيات المشروع
يجب أن يعتمد المشروع على مكتبة دعم MDC Android. من المفترض أن يكون نموذج الرمز الذي نزّلته يتضمّن هذا العنصر المُستخدَم، ولكن من الجيد اتّباع الخطوات التالية للتأكّد من ذلك.
- انتقِل إلى ملف
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
بسيطًا في نموذج الرمز البرمجي لعرض الأجزاء والتنقّل بينها.
افتح MainActivity.kt
في الدليل shrine -> app -> src -> main -> java -> com.google.codelabs.mdc.kotlin.shrine
. يجب أن يحتوي على ما يلي:
MainActivity.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
class MainActivity : AppCompatActivity(), NavigationHost {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.shr_main_activity)
if (savedInstanceState == null) {
supportFragmentManager
.beginTransaction()
.add(R.id.container, LoginFragment())
.commit()
}
}
override fun navigateTo(fragment: Fragment, addToBackstack: Boolean) {
val transaction = supportFragmentManager
.beginTransaction()
.replace(R.id.container, fragment)
if (addToBackstack) {
transaction.addToBackStack(null)
}
transaction.commit()
}
}
يعرض هذا النشاط ملف تنسيق R.layout.shr_main_activity
، الذي تم تحديده في shr_main_activity.xml
.
في onCreate(),
، سترى أنّ MainActivity.kt
يبدأ معاملة Fragment
لعرض LoginFragment
. في هذا الدرس التطبيقي حول الترميز، سنعمل على تعديل LoginFragment
. ينفِّذ النشاط أيضًا طريقة navigateTo(Fragment)
، محدّدة في NavigationHost
، ما يسمح لأي جزء بالانتقال إلى جزء مختلف.
Command + النقر (أو 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>
بسيطًا يعمل كحاوية لأي أجزاء يعرضها النشاط.
بعد ذلك، لنفتح LoginFragment.kt
.
LoginFragment.kt
package com.google.codelabs.mdc.kotlin.shrine
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
class LoginFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.shr_login_fragment, container, false)
return view
}
}
يضخم LoginFragment
ملف التنسيق shr_login_fragment
ويعرضه في 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" />
</LinearLayout>
</ScrollView>
في هذا المثال، يظهر الرمز <LinearLayout>
مع الرمز <ImageView>
في أعلى الشاشة، ما يمثّل شعار Shrine.
بعد ذلك، ستظهر علامة <TextView>
تمثّل تصنيف الضريح تحت الشعار. نص هذا التصنيف هو مورد سلسلة باسم @string/shr_app_name
. إذا ضغطت على Command + Click (أو Control + Click) على اسم مورد السلسلة أو فتحت app -> res -> values -> strings.xml
، يمكنك الاطّلاع على ملف strings.xml
الذي يتم فيه تعريف موارد السلاسل. عند إضافة المزيد من موارد السلسلة في المستقبل، سيتم تحديدها هنا. يجب أن يحتوي كل مورد في هذا الملف على بادئة shr_
للإشارة إلى أنّه جزء من تطبيق Shrine.
بعد أن تعرّفت على رمز إجراء التفعيل، لنبدأ بتنفيذ المكوّن الأول.
3- إضافة حقول نصية
في البداية، سنضيف حقلَي نص إلى صفحة تسجيل الدخول ليتمكّن المستخدمون من إدخال اسم المستخدم وكلمة المرور. سنستخدم مكوّن "حقل النص" في MDC، الذي يتضمّن وظائف مضمّنة تعرِض تصنيفًا عائمًا ورسائل خطأ.
إضافة XML
في shr_login_fragment.xml
، أضِف عنصرَي TextInputLayout
يتضمّنان عنصرًا فرعيًا TextInputEditText
داخل <LinearLayout>
، أسفل تصنيف <TextView>
"SHRINE":
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" />
</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
للاطّلاع على موارد السلاسل هذه.
strings.xml
<string name="shr_hint_username">Username</string>
<string name="shr_hint_password">Password</string>
إضافة عملية التحقّق من صحة الإدخال
TextInputLayout
توفّر مكوّنات وظائف مضمّنة لملاحظات الأخطاء.
لعرض الملاحظات والآراء عن الأخطاء، يُرجى إجراء التغييرات التالية على "shr_login_fragment.xml
":
- اضبط السمة
app:errorEnabled
علىtrue
في عنصر كلمة المرورTextInputLayout
. سيؤدي ذلك إلى إضافة مساحة إضافية لرسالة الخطأ أسفل حقل النص. - اضبط السمة
android:inputType
على "textPassword
" في عنصر كلمة المرورTextInputEditText
. سيؤدي ذلك إلى إخفاء نص الإدخال في حقل كلمة المرور.
بعد إجراء هذه التغييرات، من المفترض أن تظهر حقول النصوص في 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" />
</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>
جرِّب الآن تشغيل التطبيق. من المفترض أن تظهر لك صفحة تتضمّن حقلَي نصّ "اسم المستخدم" و"كلمة المرور".
اطلع على الرسوم المتحركة للتصنيف العائم:
4. إضافة أزرار
بعد ذلك، سنضيف زرَّين إلى صفحة تسجيل الدخول: "إلغاء" و"التالي". سنستخدم مكوّن زر Material Design الذي يتضمّن تأثير تموج الحبر المميّز في 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>
هذا كل شيء! عند تشغيل التطبيق، ستظهر موجة الحبر عند النقر على كل زر.
5- الانتقال إلى الجزء التالي
أخيرًا، سنضيف بعض رمز Kotlin إلى LoginFragment.kt
لربط زر "التالي" بالانتقال إلى جزء آخر.
لنضيف طريقة منطقية خاصة isPasswordValid
في LoginFragment.kt
ضمن onCreateView()
، مع منطق لتحديد ما إذا كانت كلمة المرور صالحة أم لا. لأغراض هذا العرض التوضيحي، سنتأكد فقط من أن كلمة المرور تتكون من 8 أحرف على الأقل:
LoginFragment.kt
private fun isPasswordValid(text: Editable?): Boolean {
return text != null && text.length >= 8
}
بعد ذلك، أضِف مستمعًا للنقر إلى الزر "التالي" الذي يضبط الخطأ ويزيله استنادًا إلى طريقة isPasswordValid()
التي أنشأناها للتو. في onCreateView()
، يجب وضع أداة معالجة النقرات هذه بين خط المنتفخ وخط return view
.
لنضِف الآن أداة معالجة رئيسية إلى كلمة المرور TextInputEditText
للاستماع إلى الأحداث الرئيسية التي من شأنها محو الخطأ. يجب أن يستخدم هذا المستمع أيضًا isPasswordValid()
للتحقّق مما إذا كانت كلمة المرور صالحة أم لا. يمكنك إضافة هذا الإجراء مباشرةً تحت مستمع النقرات في onCreateView()
.
يُفترض أن تبدو طريقة onCreateView() الآن على النحو التالي:
LoginFragment.kt
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment.
val view = inflater.inflate(R.layout.shr_login_fragment, container, false)
// Set an error if the password is less than 8 characters.
view.next_button.setOnClickListener({
if (!isPasswordValid(password_edit_text.text!!)) {
password_text_input.error = getString(R.string.shr_error_password)
} else {
// Clear the error.
password_text_input.error = null
}
})
// Clear the error once more than 8 characters are typed.
view.password_edit_text.setOnKeyListener({ _, _, _ ->
if (isPasswordValid(password_edit_text.text!!)) {
// Clear the error.
password_text_input.error = null
}
false
})
return view
}
}
الآن، يمكننا الانتقال إلى جزء آخر. في onCreateView()
، يمكنك تعديل OnClickListener
للانتقال إلى جزء آخر عند إتمام عملية التحقّق من الأخطاء بنجاح. من المفترض أن يظهر رمز clickListener
الآن على النحو التالي:
LoginFragment.kt
// Set an error if the password is less than 8 characters.
view.next_button.setOnClickListener({
if (!isPasswordValid(password_edit_text.text!!)) {
password_text_input.error = getString(R.string.shr_error_password)
} else {
// Clear the error.
password_text_input.error = null
// Navigate to the next Fragment.
(activity as NavigationHost).navigateTo(ProductGridFragment(), false)
}
})
أضفنا السطر (
activity
as
NavigationHost).navigateTo(ProductGridFragment(),
false
)
إلى الحالة else
لأداة معالجة النقرات. يستدعي هذا السطر الطريقة navigateTo()
من MainActivity
للانتقال إلى جزء جديد وهو ProductGridFragment
. هذه صفحة فارغة حاليًا يمكنك العمل عليها في MDC-102.
الآن، أنشئ التطبيق. انطلق واضغط على زر "التالي".
رائع! ستكون هذه الشاشة نقطة الانطلاق في الدروس التطبيقية التالية حول الترميز التي ستعمل عليها في MDC-102.
6- تم
باستخدام ترميز XML أساسي و30 سطرًا تقريبًا من لغة Kotlin، ساعدتك مكتبة Material Components لنظام التشغيل Android في إنشاء صفحة تسجيل دخول جميلة تتوافق مع إرشادات تصميم المواد، وتبدو أيضًا متسقة في المظهر والسلوك على جميع الأجهزة.
الخطوات التالية
يعد الحقل النصي والزر مكونين أساسيين في مكتبة MDC لنظام التشغيل Android، ولكن هناك المزيد! يمكنك الاطّلاع على باقي المكوّنات في تطبيق MDC Android. يمكنك بدلاً من ذلك الانتقال إلى MDC 102: بنية التصميم المتعدد الأبعاد والتنسيق للتعرّف على شريط التطبيق العلوي وعرض البطاقة وتنسيق الشبكة. نشكرك على تجربة Material Components. نأمل أن تكون قد استفدت من هذا الدرس التطبيقي حول الترميز.