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

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

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

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

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

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

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

صورة GIF تعرض التعديلات في الوقت الفعلي باستخدام Compose
Preview

يمكنك إضافة مَعلمات يدويًا في الرمز لتخصيص طريقة عرض "استوديو Android" للتعليق التوضيحي @Preview. يمكنك حتى إضافة التعليق التوضيحي @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 لتحديد عمليات الضبط لعناصرك المركّبة على أجهزة مختلفة.

مثال على دالة قابلة للإنشاء

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

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

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

Spec
list

للتطبيق، اضغط على 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")
}

مستطيل أخضر مكتوب عليه "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

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

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

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

نسخ عرض @Preview

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

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

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

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

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

تقدّم androidx.compose.ui:ui-tooling-preview 1.6.0-alpha01+ نماذج واجهة برمجة تطبيقات المعاينات المتعددة: @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 القابلة للإنشاء

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

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

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

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

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

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,
)

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

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

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

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

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

المعاينات وViewModels

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

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

لوحة المشاكل في &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 Tooling.