توفّر Jetpack Compose تنفيذًا للإصدار Material Design، وهو نظام تصميم شامل لإنشاء واجهات رقمية. تم إنشاء مكونات التصميم المتعدد الأبعاد (الأزرار والبطاقات والمفاتيح وما إلى ذلك) باستخدام تصميم المواد، وهي طريقة منهجية لتخصيص "التصميم المتعدد الأبعاد" ليعكس بشكل أفضل العلامة التجارية لمنتجك. يحتوي مظهر Material على سمات اللون وأسلوب الخط والشكل. عند تخصيص هذه السمات، تنعكس التغييرات التي أجريتها تلقائيًا في المكوّنات التي تستخدمها لإنشاء تطبيقك.
تنفّذ Jetpack Compose هذه المفاهيم باستخدام عنصر MaterialTheme
القابل للإنشاء:
MaterialTheme( colors = // ... typography = // ... shapes = // ... ) { // app content }
اضبط المَعلمات التي تمرِّرها إلى MaterialTheme
لتصميم تطبيقك.
الشكل 1. تعرض لقطة الشاشة الأولى تطبيقًا لم يتم ضبط
MaterialTheme
فيه، ولذلك يستخدم النمط التلقائي. تعرض لقطة الشاشة الثانية تطبيقًا يمرّر المعلمات إلى MaterialTheme
لتخصيص النمط.
اللون
يتم وضع نماذج للألوان في Compose باستخدام الفئة Color
، وهي فئة بسيطة للاحتفاظ بالبيانات.
val Red = Color(0xffff0000) val Blue = Color(red = 0f, green = 0f, blue = 1f)
في حين يمكنك تنظيم هذه العناصر كيفما شئت (كثوابت عالية المستوى، داخل سينغلتون، أو تضمين محدّد)، نقترح بشدة تحديد الألوان في المظهر واسترداد الألوان منها. ويتيح هذا الأسلوب التوافق مع المظهر الداكن والمظاهر المدمجة.
الشكل 2. نظام الألوان Material.
يوفر Compose الفئة Colors
لتصميم نموذج نظام الألوان المتعدد الأبعاد. توفر Colors
دوال الإنشاء لإنشاء مجموعات من الألوان light أو الداكنة:
private val Yellow200 = Color(0xffffeb46) private val Blue200 = Color(0xff91a4fc) // ... private val DarkColors = darkColors( primary = Yellow200, secondary = Blue200, // ... ) private val LightColors = lightColors( primary = Yellow500, primaryVariant = Yellow400, secondary = Blue700, // ... )
بعد تحديد Colors
، يمكنك تمريرها إلى MaterialTheme
:
MaterialTheme( colors = if (darkTheme) DarkColors else LightColors ) { // app content }
استخدام ألوان المظاهر
يمكنك استرداد Colors
المقدمة إلى MaterialTheme
القابل للإنشاء باستخدام MaterialTheme.colors
.
Text( text = "Hello theming", color = MaterialTheme.colors.primary )
لون السطح والمحتوى
تقبل العديد من المكونات زوجًا من الألوان ولون المحتوى:
Surface( color = MaterialTheme.colors.surface, contentColor = contentColorFor(color), // ... ) { /* ... */ } TopAppBar( backgroundColor = MaterialTheme.colors.primarySurface, contentColor = contentColorFor(backgroundColor), // ... ) { /* ... */ }
يتيح لك ذلك ليس فقط ضبط لون العنصر القابل للإنشاء، ولكن أيضًا يتيح لك توفير لون تلقائي للمحتوى للعناصر القابلة للإنشاء المضمّنة فيه. تستخدم العديد من العناصر
القابلة للإنشاء لون المحتوى هذا تلقائيًا. على سبيل المثال، يعتمد Text
لونه على لون المحتوى الرئيسي، ويستخدم Icon
هذا اللون لضبط درجة اللون.
الشكل 3. يؤدي تعيين ألوان خلفية مختلفة إلى إنتاج ألوان مختلفة للنص والرموز.
تسترد الطريقة contentColorFor()
لون "on"
المناسب لأي ألوان مظهر. على سبيل المثال، عند ضبط لون خلفية primary
على Surface
، يتم استخدام هذه الدالة لضبط onPrimary
على أنّه لون المحتوى. إذا قمت بتعيين لون خلفية غير تابع للمظهر، يجب عليك أيضًا تحديد لون محتوى مناسب. استخدِم LocalContentColor
لاسترداد لون المحتوى المفضّل للخلفية الحالية، في
موضع معيّن في التسلسل الهرمي.
محتوى ألفا
غالبًا ما ترغب في تغيير مقدار التأكيد على المحتوى لتوصيل الأهمية وتوفير التسلسل الهرمي المرئي. تنصح اقتراحات بشأن وضوح النص في "التصميم المتعدد الأبعاد" باستخدام مستويات مختلفة من التعتيم لنقل مستويات أهمية مختلفة.
تنفِّذ Jetpack Compose هذا الإجراء من خلال LocalContentAlpha
.
يمكنك تحديد ألفا المحتوى للتسلسل الهرمي من خلال تقديم قيمة
لسمة CompositionLocal
هذه.
يمكن للعناصر القابلة للإنشاء المُدمجة استخدام هذه القيمة لتطبيق معالجة ألفا على المحتوى.
على سبيل المثال، يستخدم Text
وIcon
بشكل تلقائي مجموعة LocalContentColor
بعد تعديلها لاستخدام LocalContentAlpha
. تحدد المادة بعض قيم ألفا العادية (high
وmedium
وdisabled
) التي يتم تصميمها باستخدام العنصر ContentAlpha
.
// By default, both Icon & Text use the combination of LocalContentColor & // LocalContentAlpha. De-emphasize content by setting content alpha CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) { Text( // ... ) } CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) { Icon( // ... ) Text( // ... ) }
للمزيد من المعلومات عن "CompositionLocal
"، يمكنك الاطّلاع على البيانات ذات النطاق المحلي باستخدام
دليل IndustryLocal.
الشكل 4. تطبيق مستويات مختلفة من التوكيد على النص لتوصيل التسلسل
الهرمي للمعلومات بصريًا. السطر الأول من النص هو العنوان ويحتوي على المعلومات الأكثر أهمية، وبالتالي يستخدم السمة ContentAlpha.high
. يحتوي السطر الثاني على بيانات وصفية أقل أهمية، وبالتالي يستخدم ContentAlpha.medium
.
المظهر الداكن
في Compose، يمكنك تنفيذ المظاهر الفاتحة والداكنة من خلال توفير مجموعات مختلفة من
Colors
إلى MaterialTheme
القابل للإنشاء:
@Composable fun MyTheme( darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit ) { MaterialTheme( colors = if (darkTheme) DarkColors else LightColors, /*...*/ content = content ) }
في هذا المثال، يتم تضمين MaterialTheme
في دالة قابلة للإنشاء،
وتقبل معلَمة تحدّد ما إذا كان يجب استخدام مظهر داكن أم لا. في هذه الحالة، تحصل الدالة على القيمة التلقائية لـ darkTheme
من خلال طلب البحث عن إعدادات مظهر الجهاز.
يمكنك استخدام رمز كهذا للتأكد مما إذا كانت قيمة Colors
الحالية فاتحة أو داكنة:
val isLightTheme = MaterialTheme.colors.isLight Icon( painterResource( id = if (isLightTheme) { R.drawable.ic_sun_24 } else { R.drawable.ic_moon_24 } ), contentDescription = "Theme" )
تراكبات الارتفاع
في Material، يتم استقبال الأسطح في المظاهر الداكنة ذات الارتفاعات الأعلى تراكبات المسقط الرأسي، التي تعمل على إضاءة الخلفية. كلما كان ارتفاع السطح (رفعه أقرب إلى مصدر ضوء ضمني)، أصبح هذا السطح أفتح.
يتم تطبيق هذه التراكبات تلقائيًا من خلال Surface
القابلة للإنشاء عند استخدام الألوان الداكنة، وبالنسبة إلى أي مادة أخرى قابلة للإنشاء تستخدم سطحًا:
Surface( elevation = 2.dp, color = MaterialTheme.colors.surface, // color will be adjusted for elevation /*...*/ ) { /*...*/ }
الشكل 5. تستخدم كل من البطاقات وشريط التنقل السفلي اللون surface
كخلفية. نظرًا لأن البطاقات والتنقل السفلي يقعان على مستويات ارتفاع مختلفة فوق الخلفية، فإن ألوانها مختلفة قليلاً - البطاقات أفتح من الخلفية والتنقل السفلي
أفتح من البطاقات.
بالنسبة إلى السيناريوهات المخصّصة التي لا تتضمّن Surface
، استخدِم
LocalElevationOverlay
،
وCompositionLocal
يحتوي على
ElevationOverlay
الذي تستخدمه
Surface
المكوّنات:
// Elevation overlays // Implemented in Surface (and any components that use it) val color = MaterialTheme.colors.surface val elevation = 4.dp val overlaidColor = LocalElevationOverlay.current?.apply( color, elevation )
لإيقاف تراكبات المسقط الرأسي، قدّم null
عند النقطة المطلوبة في تدرج هرمي قابل للإنشاء:
MyTheme { CompositionLocalProvider(LocalElevationOverlay provides null) { // Content without elevation overlays } }
لهجات ألوان محدودة
تنصح Material بتطبيق لكنات ألوان محدودة للمظاهر الداكنة من خلال تفضيل استخدام اللون surface
على اللون primary
في
معظم الحالات. تنفِّذ المواد القابلة للإنشاء مثل TopAppBar
وBottomNavigation
هذا السلوك تلقائيًا.
الشكل 6. مظهر متعدد الأبعاد مع لمسات ألوان محدودة. يستخدم شريط التطبيق العلوي اللون الأساسي في المظهر الفاتح ولون السطح في "المظهر الداكن".
بالنسبة إلى السيناريوهات المخصّصة، استخدِم سمة
الإضافة primarySurface
:
Surface( // Switches between primary in light theme and surface in dark theme color = MaterialTheme.colors.primarySurface, /*...*/ ) { /*...*/ }
أسلوب الخط
تحدد Material نظام الكتابة الذي يشجعك على استخدام عدد صغير من الأنماط ذات الأسماء الدلالية.
الشكل 7. نظام نوع Material.
تنفِّذ ميزة Compose نظام الأنواع من خلال الفئات Typography
وTextStyle
والخطوط. تقدم الدالة الإنشائية Typography
إعدادات تلقائية لكل نمط حتى تتمكن من حذف أي نمط لا تريد تخصيصه:
val raleway = FontFamily( Font(R.font.raleway_regular), Font(R.font.raleway_medium, FontWeight.W500), Font(R.font.raleway_semibold, FontWeight.SemiBold) ) val myTypography = Typography( h1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W300, fontSize = 96.sp ), body1 = TextStyle( fontFamily = raleway, fontWeight = FontWeight.W600, fontSize = 16.sp ) /*...*/ ) MaterialTheme(typography = myTypography, /*...*/) { /*...*/ }
إذا كنت تريد استخدام الخط الطباعي نفسه في كل أنحاء المكان، حدِّد defaultFontFamily parameter
واحذف fontFamily
لأي من عناصر TextStyle
:
val typography = Typography(defaultFontFamily = raleway) MaterialTheme(typography = typography, /*...*/) { /*...*/ }
استخدام أنماط النص
يمكن الوصول إلى TextStyle
من خلال MaterialTheme.typography
. يمكنك استرداد
TextStyle
كما يلي:
Text( text = "Subtitle2 styled", style = MaterialTheme.typography.subtitle2 )
الشكل 8. استخدم مجموعة مختارة من الخطوط الطباعية والأنماط للتعبير عن علامتك التجارية.
شكل
تحدد المادة نظام الشكل، ما يسمح لك بتحديد الأشكال للمكونات الكبيرة والمتوسطة والصغيرة.
الشكل 9. نظام شكل Material.
ينفِّذ Compose نظام الأشكال باستخدام الفئة
Shapes
، التي تتيح
لك تحديد
CornerBasedShape
لكل فئة حجم:
val shapes = Shapes( small = RoundedCornerShape(percent = 50), medium = RoundedCornerShape(0f), large = CutCornerShape( topStart = 16.dp, topEnd = 0.dp, bottomEnd = 0.dp, bottomStart = 16.dp ) ) MaterialTheme(shapes = shapes, /*...*/) { /*...*/ }
تستخدم العديد من المكونات هذه الأشكال بشكل افتراضي. على سبيل المثال،
Button
وTextField
وFloatingActionButton
القيمة التلقائية هي "صغير"
وAlertDialog
الضبط التلقائي على "متوسط"
وModalDrawer
القيم التلقائية على "كبير"، يمكنك الاطّلاع على
مرجع مخطّط الشكل
للربط الكامل.
استخدام الأشكال
يمكن الوصول إلى Shape
من خلال MaterialTheme.shapes
. استرجع Shape
برمز مثل هذا:
Surface( shape = MaterialTheme.shapes.medium, /*...*/ ) { /*...*/ }
الشكل 10. استخدم الأشكال للتعبير عن العلامة التجارية أو الحالة.
الأنماط التلقائية
ما من مفهوم مكافئ في إنشاء الأنماط التلقائية من مشاهدات Android. يمكنك توفير وظائف مماثلة من خلال إنشاء الدوال القابلة للإنشاء "التحميل الزائد" التي تلفّ مكونات Material. على سبيل المثال، لإنشاء نمط للأزرار، عليك لفّ أحد الأزرار في الدالة القابلة للإنشاء، مع ضبط المَعلمات التي تريد تغييرها مباشرةً، وعرض المَعلمات الأخرى كمعلَمات للعنصر القابل للإنشاء الذي يحتوي على تلك العناصر.
@Composable fun MyButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary ), onClick = onClick, modifier = modifier, content = content ) }
تراكبات المظاهر
يمكنك تحقيق ما يكافئ
تراكبات المظاهر من مشاهدات Android في Compose، من خلال دمج
MaterialTheme
العناصر القابلة للإنشاء. بما أنّ MaterialTheme
تضبط الألوان وأسلوب الخط والأشكال تلقائيًا على قيمة المظهر الحالية، إذا ضبط المظهر إحدى هذه المَعلمات فقط، تحتفظ المَعلمات الأخرى بقيمها التلقائية.
بالإضافة إلى ذلك، يجب الانتباه إلى استخدامات السمة android:theme
عند نقل الشاشات المستندة إلى العرض إلى ميزة "الكتابة". من المحتمل أنّك بحاجة إلى MaterialTheme
جديد في ذلك الجزء من شجرة واجهة المستخدم الخاصة بالإنشاء.
في نموذج البوم، تستخدم شاشة التفاصيل PinkTheme
لمعظم أجزاء الشاشة، ثم BlueTheme
للقسم ذي الصلة. انظر لقطة الشاشة والرمز أدناه.
الشكل 11. موضوعات مدمجة في عينة Owl.
@Composable fun DetailsScreen(/* ... */) { PinkTheme { // other content RelatedSection() } } @Composable fun RelatedSection(/* ... */) { BlueTheme { // content } }
حالات المكوّنات
إنّ مكونات Material التي يمكن التفاعل معها (بالنقر أو التبديل أو ما إلى ذلك) يمكن أن تكون في حالات مرئية مختلفة. تشمل الحالات: "مفعّل" و"غير مفعّل" و"مضغوط" وغير ذلك.
غالبًا ما تتضمّن العناصر القابلة للإنشاء معلَمة enabled
. يؤدي ضبطها على false
إلى منع التفاعل، وتغيير خصائص مثل اللون والمسقط الرأسي لنقل حالة المكوِّن بشكل مرئي.
الشكل 12. زر مع enabled = true
(لليسار) وenabled = false
(لليمين).
في معظم الحالات يمكنك الاعتماد على الإعدادات الافتراضية لقيم مثل اللون والمسقط الرأسي. إذا أردت ضبط القيم المستخدَمة في حالات مختلفة، تتوفّر فئات ودوال ملائمة. اطّلِع على مثال الزر أدناه:
Button( onClick = { /* ... */ }, enabled = true, // Custom colors for different states colors = ButtonDefaults.buttonColors( backgroundColor = MaterialTheme.colors.secondary, disabledBackgroundColor = MaterialTheme.colors.onBackground .copy(alpha = 0.2f) .compositeOver(MaterialTheme.colors.background) // Also contentColor and disabledContentColor ), // Custom elevation for different states elevation = ButtonDefaults.elevation( defaultElevation = 8.dp, disabledElevation = 2.dp, // Also pressedElevation ) ) { /* ... */ }
الشكل 13. زر مع enabled = true
(لليسار) وenabled = false
(لليمين)، مع تعديل قيم اللون والارتفاع.
أمواج
تستخدم مكونات Material الأمواج للإشارة إلى أنها يتم التفاعل معها. إذا
كنت تستخدم MaterialTheme
في التدرج الهرمي، سيتم استخدام Ripple
كقيمة
تلقائية Indication
في داخل التعديل مثل
clickable
و
indication
.
في معظم الحالات، يمكنك الاعتماد على Ripple
التلقائية. إذا أردت ضبط مظهرها، يمكنك استخدام RippleTheme
لتغيير سمات مثل اللون وألفا.
يمكنك تمديد فترة "RippleTheme
" والاستفادة من وظيفتَي
defaultRippleColor
وdefaultRippleAlpha
. يمكنك بعد ذلك توفير مظهر تموج مخصص في التدرج الهرمي باستخدام LocalRippleTheme
:
@Composable fun MyApp() { MaterialTheme { CompositionLocalProvider( LocalRippleTheme provides SecondaryRippleTheme ) { // App content } } } @Immutable private object SecondaryRippleTheme : RippleTheme { @Composable override fun defaultColor() = RippleTheme.defaultRippleColor( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) @Composable override fun rippleAlpha() = RippleTheme.defaultRippleAlpha( contentColor = MaterialTheme.colors.secondary, lightTheme = MaterialTheme.colors.isLight ) }
الشكل 14. أزرار ذات قيم تمويج مختلفة مقدَّمة من خلال RippleTheme
.
مزيد من المعلومات
لمعرفة المزيد من المعلومات عن تخصيص المواد في Compose، يُرجى الاطّلاع على المراجع الإضافية التالية.
الدروس التطبيقية حول الترميز
الفيديوهات الطويلة
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عند إيقاف JavaScript.
- أنظمة التصميم المخصّصة في Compose
- نقل البيانات من المادة 2 إلى المادة 3 في Compose
- أدوات تسهيل الاستخدام في Compose