تنظيم صفحاتك في مجموعات
يمكنك حفظ المحتوى وتصنيفه حسب إعداداتك المفضّلة.
تعرض لوحة العرض الدوّارة قائمة قابلة للتمرير السريع تتكيّف ديناميكيًا استنادًا إلى حجم النافذة. استخدِم اللوحات الدوّارة لعرض مجموعة من المحتوى ذي الصلة.
تُبرز عناصر لوحة العرض الدوّارة العناصر المرئية، ولكن يمكن أن تتضمّن أيضًا نصًا موجزًا يتكيّف مع حجم العنصر.
تتوفّر أربعة تصاميم للوحات العرض الدوّارة لتناسب حالات الاستخدام المختلفة:
التصفّح المتعدّد: يتضمّن سلعًا بأحجام مختلفة. يُنصح باستخدامها لتصفّح
العديد من العناصر في الوقت نفسه، مثل الصور.
غير محتوية: تحتوي على عناصر بحجم واحد وتتجاوز حافة الشاشة. يمكن تخصيصها لعرض المزيد من النص أو عناصر أخرى في واجهة المستخدم أعلى أو أسفل كل عنصر.
الصورة الرئيسية: تعرض صورة كبيرة واحدة للتركيز عليها، كما تعرض لمحة عن المحتوى التالي من خلال عنصر صغير. يُنصح باستخدامها لتسليط الضوء على المحتوى الذي تريد التركيز عليه، مثل الصور المصغّرة للأفلام أو البرامج التلفزيونية.
ملء الشاشة: يعرض عنصرًا كبيرًا واحدًا من الحافة إلى الحافة في كل مرة، ويمكنك الانتقال للأعلى أو للأسفل. يُنصح به للمحتوى الذي يكون ارتفاعه أكبر من عرضه.
الشكل 1. أنواع منصات العرض الدوّارة غير المضمّنة (1) وملء الشاشة (2)
توضّح لك هذه الصفحة كيفية تنفيذ تنسيقات العرض المتعدد وتنسيقات لوحات العرض الدوّارة غير المضمّنة. يمكنك الاطّلاع على إرشادات Material 3 الخاصة بلوحات العرض الدوّارة للحصول على مزيد من المعلومات حول أنواع التنسيقات.
state: مثيل CarouselState يدير فهرس العنصر الحالي وموضع التمرير. أنشئ هذه الحالة باستخدام rememberCarouselState { itemCount }،
حيث itemCount هو إجمالي عدد العناصر في لوحة العرض الدوّارة.
itemSpacing: تحدّد هذه السمة مقدار المساحة الفارغة بين العناصر المتجاورة في لوحة العرض الدوّارة.
contentPadding: يطبّق مساحة متروكة حول مساحة المحتوى في لوحة العرض الدوّارة. استخدِم هذه السمة لإضافة مساحة قبل العنصر الأول أو بعد العنصر الأخير، أو لتوفير هوامش للعناصر ضمن المنطقة القابلة للتمرير.
content: دالة قابلة للإنشاء تستقبل فهرسًا صحيحًا. استخدِم دالة lambda هذه لتحديد واجهة المستخدم لكل عنصر في منصة العرض ذات العناصر المتغيّرة استنادًا إلى الفهرس.
تختلف هذه العناصر القابلة للإنشاء في طريقة تحديد حجم العناصر:
itemWidth (لـ HorizontalUncontainedCarousel): تحدّد العرض الدقيق لكل عنصر في منصة عرض بعناصر متغيّرة غير مضمّنة.
preferredItemWidth (لـ HorizontalMultiBrowseCarousel): يشير إلى العرض المثالي للعناصر في لوحة عرض دوّارة متعددة الاستعراض، ما يتيح للمكوّن عرض عناصر متعددة إذا سمحت المساحة بذلك.
مثال: رف دائري متعدد الاستخدامات
تنفّذ هذه المقتطفة لوحة عرض دوّارة متعددة الاستعراض:
تحدّد هذه السمة CarouselItem فئة بيانات، وهي تنظّم البيانات لكل عنصر في لوحة العرض الدوّارة.
تنشئ هذه السمة List من عناصر CarouselItem وتتذكّرها، ويتم ملؤها بموارد الصور والأوصاف.
يستخدم العنصر القابل للإنشاء HorizontalMultiBrowseCarousel المصمّم لعرض عناصر متعددة في لوحة عرض دوّارة.
يتم ضبط حالة لوحة العرض الدوّارة في البداية باستخدام rememberCarouselState، الذي يتم إعطاؤه إجمالي عدد العناصر.
تحتوي العناصر على preferredItemWidth (هنا، 186.dp)، ما يشير إلى عرض مثالي لكل عنصر. يستخدم هذا الإعداد لتحديد عدد العناصر التي يمكن أن تظهر على الشاشة في الوقت نفسه.
تضيف المَعلمة itemSpacing فجوة صغيرة بين العناصر.
تكرّر دالة lambda اللاحقة في HorizontalMultiBrowseCarouselCarouselItems. في كل تكرار، يتم استرداد العنصر في الفهرس i وعرض عنصر Image قابل للإنشاء.
تطبّق Modifier.maskClip(MaterialTheme.shapes.extraLarge) قناع شكل محدّدًا مسبقًا على كل صورة، ما يمنحها زوايا مستديرة.
يوفّر contentDescription وصفًا مناسبًا لذوي الاحتياجات الخاصة للصورة.
النتيجة
تعرض الصورة التالية النتيجة من المقتطف السابق:
الشكل 2. لوحة عرض دوّارة متعددة الاستعراض، مع قصّ آخر عنصر
مثال: لوحة عرض دوّارة غير مضمّنة
تنفّذ المقتطفة التالية لوحة عرض دوّارة غير مضمّنة:
تحدّد المَعلمة itemWidth عرضًا ثابتًا لكل عنصر في لوحة العرض الدوّارة.
النتيجة
تعرض الصورة التالية النتيجة من المقتطف السابق:
الشكل 3. لوحة عرض دوّارة غير مضمّنة، حيث لا يتم اقتصاص العنصر الأخير في لوحة العرض الدوّارة
يخضع كل من المحتوى وعيّنات التعليمات البرمجية في هذه الصفحة للتراخيص الموضحّة في ترخيص استخدام المحتوى. إنّ Java وOpenJDK هما علامتان تجاريتان مسجَّلتان لشركة Oracle و/أو الشركات التابعة لها.
تاريخ التعديل الأخير: 2025-08-31 (حسب التوقيت العالمي المتفَّق عليه)
[[["يسهُل فهم المحتوى.","easyToUnderstand","thumb-up"],["ساعَدني المحتوى في حلّ مشكلتي.","solvedMyProblem","thumb-up"],["غير ذلك","otherUp","thumb-up"]],[["لا يحتوي على المعلومات التي أحتاج إليها.","missingTheInformationINeed","thumb-down"],["الخطوات معقدة للغاية / كثيرة جدًا.","tooComplicatedTooManySteps","thumb-down"],["المحتوى قديم.","outOfDate","thumb-down"],["ثمة مشكلة في الترجمة.","translationIssue","thumb-down"],["مشكلة في العيّنات / التعليمات البرمجية","samplesCodeIssue","thumb-down"],["غير ذلك","otherDown","thumb-down"]],["تاريخ التعديل الأخير: 2025-08-31 (حسب التوقيت العالمي المتفَّق عليه)"],[],[],null,["A carousel displays a scrollable list of items that adapt dynamically based on\nwindow size. Use carousels to showcase a collection of related content.\nCarousel items emphasize visuals, but can also contain brief text that adapts to\nthe item size.\n\nThere are four carousel layouts available to suit different use cases:\n\n- **Multi-browse**: Includes differently sized items. Recommended for browsing many items at once, like photos.\n- **Uncontained**: Contains items that are a single size and flow past the edge of the screen. Can be customized to show more text or other UI above or below each item.\n- **Hero**: Highlights one large image to focus on and provides a peek of what's next with a small item. Recommended for spotlighting content that you want to emphasize, like movie or show thumbnails.\n- **Full-screen**: Shows one edge-to-edge large item at a time and scrolls vertically. Recommended for content that is taller than it is wide.\n\n**Figure 1.** Uncontained (1) and full-screen (2) carousel types.\n\nThis page shows you how to implement the multi-browse and uncontained carousel\nlayouts. See the [Carousel Material 3 guidelines](https://m3.material.io/components/carousel/overview) for\nmore information about the layout types.\n\nAPI surface\n\nTo implement multi-browse and uncontained carousels, use the\n[`HorizontalMultiBrowseCarousel`](/reference/kotlin/androidx/compose/material3/carousel/package-summary#HorizontalMultiBrowseCarousel(androidx.compose.material3.carousel.CarouselState,androidx.compose.ui.unit.Dp,androidx.compose.ui.Modifier,androidx.compose.ui.unit.Dp,androidx.compose.foundation.gestures.TargetedFlingBehavior,androidx.compose.ui.unit.Dp,androidx.compose.ui.unit.Dp,androidx.compose.foundation.layout.PaddingValues,kotlin.Function2)) and [`HorizontalUncontainedCarousel`](/reference/kotlin/androidx/compose/material3/carousel/package-summary#HorizontalUncontainedCarousel(androidx.compose.material3.carousel.CarouselState,androidx.compose.ui.unit.Dp,androidx.compose.ui.Modifier,androidx.compose.ui.unit.Dp,androidx.compose.foundation.gestures.TargetedFlingBehavior,androidx.compose.foundation.layout.PaddingValues,kotlin.Function2))\ncomposables. These composables share the following key parameters:\n\n- `state`: A `CarouselState` instance that manages the current item index and scroll position. Create this state using `rememberCarouselState { itemCount }`, where `itemCount` is the total number of items in the carousel.\n- `itemSpacing`: Defines the amount of empty space between adjacent items in the carousel.\n- `contentPadding`: Applies padding around the content area of the carousel. Use this to add space before the first item or after the last item, or to provide margins for the items within the scrollable region.\n- `content`: A composable function that receives an integer index. Use this lambda to define the UI for each item in the carousel based on its index.\n\nThese composables differ in how they specify item sizing:\n\n- `itemWidth` (for `HorizontalUncontainedCarousel`): Specifies the exact width for each item in an uncontained carousel.\n- `preferredItemWidth` (for `HorizontalMultiBrowseCarousel`): Suggests the ideal width for items in a multi-browse carousel, letting the component display multiple items if space permits.\n\nExample: Multi-browse carousel\n\nThis snippet implements a multi-browse carousel:\n\n\n```kotlin\n@Composable\nfun CarouselExample_MultiBrowse() {\n data class CarouselItem(\n val id: Int,\n @DrawableRes val imageResId: Int,\n val contentDescription: String\n )\n\n val items = remember {\n listOf(\n CarouselItem(0, R.drawable.cupcake, \"cupcake\"),\n CarouselItem(1, R.drawable.donut, \"donut\"),\n CarouselItem(2, R.drawable.eclair, \"eclair\"),\n CarouselItem(3, R.drawable.froyo, \"froyo\"),\n CarouselItem(4, R.drawable.gingerbread, \"gingerbread\"),\n )\n }\n\n HorizontalMultiBrowseCarousel(\n state = rememberCarouselState { items.count() },\n modifier = Modifier\n .fillMaxWidth()\n .wrapContentHeight()\n .padding(top = 16.dp, bottom = 16.dp),\n preferredItemWidth = 186.dp,\n itemSpacing = 8.dp,\n contentPadding = PaddingValues(horizontal = 16.dp)\n ) { i -\u003e\n val item = items[i]\n Image(\n modifier = Modifier\n .height(205.dp)\n .maskClip(MaterialTheme.shapes.extraLarge),\n painter = painterResource(id = item.imageResId),\n contentDescription = item.contentDescription,\n contentScale = ContentScale.Crop\n )\n }\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/compose/snippets/src/main/java/com/example/compose/snippets/components/Carousel.kt#L44-L82\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- Defines a `CarouselItem` data class, which structures the data for each element in the carousel.\n- Creates and remembers a `List` of `CarouselItem` objects that are populated with image resources and descriptions.\n- Uses the `HorizontalMultiBrowseCarousel` composable, which is designed for displaying multiple items in a carousel.\n - The carousel's state is initialized using `rememberCarouselState`, which is given the total count of items.\n - Items have a `preferredItemWidth` (here, `186.dp`), which suggests an optimal width for each item. The carousel uses this to determine how many items can fit on the screen at once.\n - The `itemSpacing` parameter adds a small gap between items.\n - The trailing lambda of `HorizontalMultiBrowseCarousel` iterates through the `CarouselItems`. In each iteration, it retrieves the item at index `i` and renders an `Image` composable for it.\n - `Modifier.maskClip(MaterialTheme.shapes.extraLarge)` applies a predefined shape mask to each image, giving it rounded corners.\n - `contentDescription` provides an accessibility description for the image.\n\nResult\n\nThe following image shows the result from the preceding snippet:\n**Figure 2.** A multi-browse carousel, with the last item clipped.\n\nExample: Uncontained carousel\n\nThe following snippet implements an uncontained carousel:\n\n\n```kotlin\n@Composable\nfun CarouselExample() {\n data class CarouselItem(\n val id: Int,\n @DrawableRes val imageResId: Int,\n val contentDescription: String\n )\n\n val carouselItems = remember {\n listOf(\n CarouselItem(0, R.drawable.cupcake, \"cupcake\"),\n CarouselItem(1, R.drawable.donut, \"donut\"),\n CarouselItem(2, R.drawable.eclair, \"eclair\"),\n CarouselItem(3, R.drawable.froyo, \"froyo\"),\n CarouselItem(4, R.drawable.gingerbread, \"gingerbread\"),\n )\n }\n\n HorizontalUncontainedCarousel(\n state = rememberCarouselState { carouselItems.count() },\n modifier = Modifier\n .fillMaxWidth()\n .wrapContentHeight()\n .padding(top = 16.dp, bottom = 16.dp),\n itemWidth = 186.dp,\n itemSpacing = 8.dp,\n contentPadding = PaddingValues(horizontal = 16.dp)\n ) { i -\u003e\n val item = carouselItems[i]\n Image(\n modifier = Modifier\n .height(205.dp)\n .maskClip(MaterialTheme.shapes.extraLarge),\n painter = painterResource(id = item.imageResId),\n contentDescription = item.contentDescription,\n contentScale = ContentScale.Crop\n )\n }\n}https://github.com/android/snippets/blob/f95ab59fad80aeaf5d6a90bab8a01a126f20f44e/compose/snippets/src/main/java/com/example/compose/snippets/components/Carousel.kt#L88-L126\n```\n\n\u003cbr /\u003e\n\nKey points about the code\n\n- The `HorizontalUncontainedCarousel` composable creates the carousel layout.\n - The `itemWidth` parameter sets a fixed width for each item in the carousel.\n\nResult\n\nThe following image shows the result from the preceding snippet:\n**Figure 3.** An uncontained carousel, where the last item in the carousel is not clipped."]]