معاينة واجهة المستخدم بمعاينات قابلة للإنشاء

يتم تحديد الدالة المركّبة من خلال دالة وإضافة تعليق توضيحي إليها باستخدام @Composable:

@Composable
fun SimpleComposable() {
    Text("Hello World")
}

عنصر نصي بسيط يحتوي على الكلمات "Hello
World"

لتفعيل معاينة هذه الدالة المركّبة، أنشئ دالة مركّبة أخرى مع إضافة تعليق توضيحي لها باستخدام @Composable و@Preview. تحتوي هذه الدالة المركّبة الجديدة التي تمّت إضافة تعليقات توضيحية إليها الآن على الدالة المركّبة التي أنشأتها في البداية، SimpleComposable:

@Preview
@Composable
fun SimpleComposablePreview() {
    SimpleComposable()
}

يُعلم التعليق التوضيحي @Preview "استوديو Android" بأنّه يجب عرض هذه الدالة المركّبة في طريقة عرض التصميم لهذا الملف. يمكنك الاطّلاع على آخر الأخبار المباشرة لمعاينة الدالة المركّبة أثناء إجراء تعديلاتك.

صورة GIF تعرض التعديلات في الوقت الفعلي باستخدام ميزة "إنشاء"
"معاينة"

يمكنك إضافة مَعلمات يدويًا في الرمز البرمجي لتخصيص طريقة عرض @Preview في "استوديو Android". يمكنك أيضًا إضافة التعليق التوضيحي @Preview إلى الدالة نفسها عدة مرات لمعاينة دالة مركّبة بخصائص مختلفة.

من المزايا الأساسية لاستخدام الدوال المركّبة في @Preview هي تجنُّب الاعتماد على المحاكي في "استوديو Android". يمكنك حفظ بدء تشغيل المحاكي الذي يستهلك قدرًا كبيرًا من الذاكرة لإجراء المزيد من التغييرات النهائية على الشكل والأسلوب، وقدرة @Preview على إجراء تغييرات صغيرة في الرمز واختبارها بسهولة.

للاستفادة من التعليق التوضيحي @Preview بأكبر قدر ممكن من الفعالية، احرص على تحديد شاشاتك من حيث الحالة التي تتلقّاها كإدخال والأحداث التي تخرجها.

تحديد @Preview

يوفّر "استوديو Android" بعض الميزات لتوسيع نطاق معاينات الدوال المركّبة. يمكنك تغيير تصميم الحاوية أو التفاعل معها أو نشرها مباشرةً في محاكي أو جهاز.

الأبعاد

بشكل تلقائي، يتم اختيار أبعاد @Preview تلقائيًا لتضمين محتواها. لضبط الأبعاد يدويًا، أضِف المَعلمتَين heightDp وwidthDp. يتم تفسير هذه القيم على أنّها dp، لذا لست بحاجة إلى إضافة .dp إليها:

@Preview(widthDp = 50, heightDp = 50)
@Composable
fun SquareComposablePreview() {
    Box(Modifier.background(Color.Yellow)) {
        Text("Hello World")
    }
}

مربّع أصفر مكتوب عليه "Hello
World"

معاينة الألوان الديناميكية

إذا فعّلت ميزة الألوان الديناميكية في تطبيقك، استخدِم السمة wallpaper لتبديل الخلفيات ومعرفة كيفية تفاعل واجهة المستخدم مع الخلفية التي يختارها المستخدمون المختلفون. اختَر من بين مظاهر الخلفيات المختلفة التي توفّرها الفئة Wallpaper. تتطلّب هذه الميزة الإصدار 1.4.0 من Compose أو إصدارًا أحدث.

الاستخدام مع أجهزة مختلفة

في استوديو Android Flamingo، يمكنك تعديل مَعلمة device في تعليق Preview التوضيحي لتحديد إعدادات الدوال المركّبة في أجهزة مختلفة.

مثال على دالة
مركّبة

عندما تحتوي مَعلمة الجهاز على سلسلة فارغة (@Preview(device = ""))، يمكنك استدعاء الإكمال التلقائي بالضغط على Ctrl + Space. بعد ذلك، يمكنك تعيين قيم كل معلمة.

تعديل الدالة
النموذجية

من الإكمال التلقائي، يمكنك تحديد أي خيار جهاز من القائمة، على سبيل المثال، @Preview(device = "id:pixel_4"). يمكنك بدلاً من ذلك إدخال جهاز مخصّص من خلال اختيار spec:width=px,height=px,dpi=int… لضبط القيم الفردية لكل مَعلمة.

قائمة
المواصفات

للتطبيق، اضغط على Enter، أو للإلغاء، اضغط على Esc.

إذا ضبطت قيمة غير صالحة، سيتم وضع خط أحمر تحت البيان وقد يتوفّر حلّ (Alt + Enter (⌥ + ⏎ لنظام التشغيل macOS) > استبدال بـ …. يحاول الفحص تقديم حلّ أقرب ما يكون إلى ما أدخلته.

مثال على قيمة
غير صالحة

اللغة

لاختبار لغات مستخدمين مختلفة، أضِف المَعلمة locale:

@Preview(locale = "fr-rFR")
@Composable
fun DifferentLocaleComposablePreview() {
    Text(text = stringResource(R.string.greeting))
}

عنصر نصي بسيط يحتوي على كلمة "Bonjour" مع العلم الفرنسي

ضبط لون الخلفية

بشكل تلقائي، يتم عرض الدالة المركّبة بخلفية شفافة. لإضافة خلفية، أضِف المَعلمتَين showBackground وbackgroundColor. يُرجى العِلم أنّ backgroundColor هو Long بتنسيق ARGB، وليس قيمة Color:

@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
    Text("Hello World")
}

مستطيل أخضر مع عبارة "مرحبًا
بالعالم"

واجهة مستخدِم النظام

إذا كنت بحاجة إلى عرض شريطَي الحالة وشريط الإجراءات داخل المعاينة، أضِف المَعلمة showSystemUi:

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}

نافذة معاينة تعرض نشاطًا مع شريطَي الحالة والإجراءات

وضع واجهة المستخدم

يمكن أن تأخذ المَعلمة uiMode أيًا من ثوابت Configuration.UI_* وتسمح لك بتغيير سلوك المعاينة وفقًا لذلك. على سبيل المثال، يمكنك ضبط المعاينة على "الوضع الليلي" لمعرفة كيف يتفاعل المظهر.

واجهة مستخدم معاينة Compose

LocalInspectionMode

يمكنك قراءة LocalInspectionMode CompositionLocal لمعرفة ما إذا كان يتم عرض الدالة المركّبة في معاينة (داخل مكوّن قابل للفحص). إذا تم عرض التركيب في معاينة، يتم تقييم LocalInspectionMode.current على أنّه true. تتيح لك هذه المعلومات تخصيص المعاينة، على سبيل المثال، يمكنك عرض صورة مؤقتة في نافذة المعاينة بدلاً من عرض بيانات حقيقية.

بهذه الطريقة، يمكنك أيضًا تجاوز القيود. على سبيل المثال، عرض عيّنات بيانات بدلاً من طلب الشبكة.

@Composable
fun GreetingScreen(name: String) {
    if (LocalInspectionMode.current) {
        // Show this text in a preview window:
        Text("Hello preview user!")
    } else {
        // Show this text in the app:
        Text("Hello $name!")
    }
}

التفاعل مع @Preview

يوفّر استوديو Android ميزات تتيح لك التفاعل مع المعاينات المحدّدة. يساعدك هذا التفاعل في فهم سلوك المعاينات أثناء التشغيل ويتيح لك التنقّل بشكل أفضل في واجهة المستخدم باستخدام المعاينات.

وضع التفاعل

يتيح لك الوضع التفاعلي التفاعل مع المعاينة بشكل مشابه لكيفية تفاعلك على جهاز يشغّل برنامجك، مثل الهاتف أو الجهاز اللوحي. يتم عزل الوضع التفاعلي في بيئة وضع الحماية (أي معزول عن المعاينات الأخرى)، حيث يمكنك النقر على العناصر وإدخال بيانات المستخدم في المعاينة. إنّها طريقة سريعة لاختبار الحالات والإيماءات المختلفة وحتى الصور المتحركة للدالة المركّبة.

ينقر المستخدم على الزر "تفاعلي" في المعاينة

فيديو للمستخدم يتفاعل مع
معاينة

التنقّل في الرموز البرمجية والمخططات القابلة للتجميع

يمكنك تمرير مؤشر الماوس فوق معاينة للاطّلاع على مخططات الدوال المركّبة المضمّنة فيها. يؤدي النقر على مخطط دالة مركّبة إلى توجيه عرض المحرِّر إلى تعريفها.

عندما يمرّر المستخدم مؤشر الماوس فوق معاينة، يعرض Studio المخططات التفصيلية
للدوال
المركّبة

عرض معاينة

يمكنك تشغيل @Preview معيّن على محاكي أو جهاز فعلي. يتم نشر النسخة الحصرية ضمن تطبيق المشروع نفسه كـ Activity جديد، لذا تتم مشاركة السياق والأذونات نفسها. ولا يتطلّب منك كتابة رمز برمجي نموذجي لطلب إذن إذا سبق منحه.

انقر على رمز تشغيل المعاينة رمز
تشغيل المعاينة بجانب التعليق التوضيحي @Preview أو في أعلى المعاينة، وسينشر Android Studio هذا التعليق التوضيحي @Preview على جهازك المتصل أو المحاكي.

ينقر المستخدم على المعاينة

فيديو للمستخدم وهو ينشر معاينة على الجهاز

نسخ عرض @Preview

يمكن نسخ كل معاينة معروضة كصورة من خلال النقر بزر الماوس الأيمن عليها.

ينقر المستخدم على معاينة لنسخها كصورة.

معاينات متعددة للتعليق التوضيحي @Preview نفسه

يمكنك عرض نُسخ متعددة من الدالة المركّبة @Preview نفسها بمواصفات مختلفة أو مَعلمات مختلفة يتم تمريرها إلى الدالة المركّبة. بهذه الطريقة، يمكنك تقليل الرمز البرمجي النموذجي الذي تحتاج إلى كتابته.

نماذج المعاينة المتعددة

androidx.compose.ui:ui-tooling-preview يقدّم الإصدار 1.6.0-alpha01 والإصدارات الأحدث نماذج واجهة برمجة التطبيقات Multipreview: @PreviewScreenSizes و@PreviewFontScales و@PreviewLightDark و@PreviewDynamicColors، بحيث يمكنك من خلال تعليق توضيحي واحد معاينة واجهة مستخدم Compose في السيناريوهات الشائعة.

معاينة الخطوط وأحجام الشاشات المختلفة باستخدام النماذج

إنشاء تعليقات توضيحية مخصّصة للمعاينة المتعدّدة

باستخدام ميزة "المعاينة المتعددة"، يمكنك تحديد فئة تعليقات توضيحية تتضمّن تعليقات توضيحية متعدّدة من النوع @Preview بإعدادات مختلفة. تؤدي إضافة هذا التعليق التوضيحي إلى دالة مركّبة إلى عرض جميع المعاينات المختلفة تلقائيًا في آن واحد. على سبيل المثال، يمكنك استخدام هذا التعليق التوضيحي لمعاينة أجهزة متعددة أو أحجام خطوط أو مظاهر متعددة في الوقت نفسه بدون تكرار هذه التعريفات لكل دالة مركّبة.

ابدأ بإنشاء فئة تعليقات توضيحية مخصّصة:

@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 1.5f
)
annotation class FontScalePreviews

يمكنك استخدام هذا التعليق التوضيحي المخصّص للدوال المركّبة الخاصة بالمعاينة:

@FontScalePreviews
@Composable
fun HelloWorldPreview() {
    Text("Hello World")
}

علامة تبويب التصميم في "استوديو Android" تعرض الدالة المركّبة بخط صغير وكبير

يمكنك الجمع بين عدة تعليقات توضيحية لمعاينة تنسيقات متعددة وتعليقات توضيحية عادية للمعاينة لإنشاء مجموعة أكثر اكتمالاً من المعاينات. لا يعني دمج تعليقات توضيحية متعددة للمعاينة أنّه يتم عرض جميع المجموعات المختلفة. بدلاً من ذلك، تعمل كل تعليقات توضيحية للمعاينة المتعددة بشكل مستقل وتعرض فقط الصيغ الخاصة بها.

@Preview(
    name = "Spanish",
    group = "locale",
    locale = "es"
)
@FontScalePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview2() {
    MaterialTheme { Surface { Text(stringResource(R.string.hello_world)) } }
}

علامة التبويب "التصميم" في "استوديو Android" التي تعرض الدالة المركّبة في جميع الإعدادات

تتيح لك طبيعة المزج والمطابقة في المعاينة المتعددة والمعاينة العادية اختبار العديد من خصائص المشاريع الأكبر حجمًا بشكل أكثر شمولاً.

‫@Preview ومجموعات البيانات الكبيرة

في كثير من الأحيان، تظهر الحاجة إلى تمرير مجموعة بيانات كبيرة إلى معاينة الدالة المركّبة. لإجراء ذلك، ما عليك سوى تمرير عيّنات بيانات إلى دالة معاينة قابلة للإنشاء من خلال إضافة مَعلمة باستخدام التعليق التوضيحي @PreviewParameter.

@Preview
@Composable
fun UserProfilePreview(
    @PreviewParameter(UserPreviewParameterProvider::class) user: User
) {
    UserProfile(user)
}

لتقديم عيّنات البيانات، أنشئ فئة تنفّذ PreviewParameterProvider وتعرض عيّنات البيانات كتسلسل.

class UserPreviewParameterProvider : PreviewParameterProvider<User> {
    override val values = sequenceOf(
        User("Elise"),
        User("Frank"),
        User("Julia")
    )
}

يؤدي ذلك إلى عرض معاينة واحدة لكل عنصر بيانات في التسلسل:

معاينات تعرض الدوال المركّبة Elise وFrank وJulia

يمكنك استخدام فئة الموفّر نفسها لعدة معاينات. إذا لزم الأمر، يمكنك تحديد عدد المعاينات من خلال ضبط مَعلمة الحدّ الأقصى.

@Preview
@Composable
fun UserProfilePreview2(
    @PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
    UserProfile(user)
}

تتم تسمية المعاينات التي تستخدم @PreviewParameter تلقائيًا باستخدام فهرس المَعلمة واسم السمة (المستخدم 0، المستخدم 1، المستخدم 2، وما إلى ذلك)، ما قد يجعل من الصعب التمييز بينها. لتحسين وضوح المعاينة، يمكنك تقديم أسماء عرض مخصّصة لكل معاينة من خلال إلغاء getDisplayName() في PreviewParameterProvider. يساعد ذلك في التمييز بين صيغ البيانات المختلفة أو حالات واجهة المستخدم. على سبيل المثال، يمكنك تصنيف المعاينات استنادًا إلى بيانات الإدخال:

class UserAgePreviewParameterProvider : PreviewParameterProvider<User> {
    // Using a List internally for efficient index-based access
    private val userList = listOf(
        User(name = "Elise", age = 30),
        User(name = "Frank", age = 31),
        User(name = "Julia", age = 40)
    )

    override val values = userList.asSequence()

    override fun getDisplayName(index: Int): String? {
        // Return null or an empty string to use the default index-based name
        val user = userList.getOrNull(index) ?: return null
        return "${user.name} - ${user.age}"
    }
}

معاينات بأسماء معروضة مخصّصة تعرض الدوال المركّبة Elise - 30 وFrank - 31 وJulia - 40

إنشاء معاينات بمساعدة الذكاء الاصطناعي

يمكن لوكيل الذكاء الاصطناعي في استوديو Android إنشاء معاينات Compose تلقائيًا للدوال المركّبة. انقر بزر الماوس الأيمن على دالة مركّبة واختَر الذكاء الاصطناعي > إنشاء معاينة لـ [اسم الدالة المركّبة]. يحلّل الوكيل الدالة المركّبة لإنشاء رمز @Preview النموذجي اللازم مع المَعلمات الصحيحة، ما يساعدك في التحقّق بسرعة من عرض واجهة المستخدم على النحو المتوقّع.

إنشاء معاينة Compose باستخدام الذكاء الاصطناعي

فئة التعليق التوضيحي @Preview

يمكنك دائمًا النقر على "ctrl أو ⌘ + النقر" على التعليق التوضيحي @Preview في Android Studio للحصول على قائمة كاملة بالمَعلمات التي يمكن تعديلها عند تخصيص المعاينة.

annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showSystemUi: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT,
    @Wallpaper val wallpaper: Int = Wallpapers.NONE,
)

القيود وأفضل الممارسات

ينفّذ &quot;استوديو Android&quot; الرموز البرمجية الخاصة بالمعاينات مباشرةً في منطقة المعاينة. ولا يتطلّب تشغيل محاكي أو جهاز فعلي لأنّه يستفيد من جزء منقول من إطار عمل Android يُسمى Layoutlib. ‫Layoutlib هو إصدار مخصّص من إطار عمل Android مصمّم للتشغيل خارج أجهزة Android. الهدف من المكتبة هو توفير معاينة لتنسيق في "استوديو Android" يكون قريبًا جدًا من عرضه على الأجهزة.

قيود المعاينة

بسبب طريقة عرض المعاينات في &quot;استوديو Android&quot;، فإنّها تكون خفيفة ولا تتطلّب عرض إطار عمل Android بالكامل. ومع ذلك، ينطوي ذلك على القيود التالية:

  • لا تتوفر إمكانية استخدام الشبكة.
  • لا يمكن الوصول إلى الملفات
  • قد لا تكون بعض واجهات برمجة تطبيقات "Context" متاحة بالكامل

المعاينات وViewModels

تكون المعاينات محدودة عند استخدام ViewModel داخل دالة مركّبة. لا يمكن لنظام المعاينات إنشاء جميع المَعلمات التي يتم تمريرها إلى ViewModel، مثل المستودعات أو حالات الاستخدام أو المدراء أو ما شابه ذلك. بالإضافة إلى ذلك، إذا كان ViewModel يشارك في حقن التبعية (مثل Hilt)، لا يمكن لنظام المعاينات إنشاء الرسم البياني الكامل للتبعية لإنشاء ViewModel.

عند محاولة معاينة دالة مركّبة باستخدام ViewModel، يعرض &quot;استوديو Android&quot; خطأً عند عرض الدالة المركّبة المحدّدة:

لوحة المشاكل في &quot;استوديو Android&quot; مع رسالة &quot;تعذّر إنشاء مثيل لـ ViewModel&quot;

إذا أردت معاينة دالة مركّبة تستخدم ViewModel، عليك إنشاء دالة مركّبة أخرى مع تمرير المَعلمات من ViewModel كوسيطات للدالة المركّبة. بهذه الطريقة، لن تحتاج إلى معاينة الدالة المركّبة التي تستخدم ViewModel.

@Composable
fun AuthorScreen(viewModel: AuthorViewModel = viewModel()) {
  AuthorScreen(
    name = viewModel.authorName,
    // ViewModel sends the network requests and makes posts available as a state
    posts = viewModel.posts
  )
}

@Composable
fun AuthorScreen(
  name: NameLabel,
  posts: PostsList
) {
  // ...
}

@Preview
@Composable
fun AuthorScreenPreview(
  // You can use some sample data to preview your composable without the need to construct the ViewModel
  name: String = sampleAuthor.name,
  posts: List<Post> = samplePosts[sampleAuthor]
) {
  AuthorScreen(
      name = NameLabel(name),
      posts = PostsList(posts)
  )
}

مراجع إضافية

  • لمزيد من المعلومات حول كيفية تعزيز "استوديو Android" لسهولة استخدام @Preview والتعرّف على المزيد من النصائح حول الأدوات، يمكنك الاطّلاع على مدونة أدوات Compose.
  • للحصول على إرشادات حول Views القديمة، يُرجى الاطّلاع على تطوير تنسيق باستخدام Views.