Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Bạn có thể điều chỉnh hình ảnh cho vừa với một hình dạng đã cắt và vẽ bóng xung quanh chu vi của hình dạng đó để tạo cảm giác ba chiều. Kỹ thuật này hữu ích cho việc tạo các thiết kế như hình đại diện và hình thu nhỏ sản phẩm hoặc hiển thị biểu trưng có hình dạng tuỳ chỉnh.
Để hiển thị hình ảnh được cắt theo một hình dạng, bạn phải làm như sau:
Tạo hình dạng.
Cắt hình ảnh theo hình dạng.
Khả năng tương thích của phiên bản
Phương thức triển khai này yêu cầu bạn phải đặt minSDK của dự án thành API cấp 21 trở lên.
Phần phụ thuộc
Tạo hình dạng
Mã sau đây tạo một hình dạng tuỳ chỉnh có thể vẽ và kết xuất một đa giác bo tròn một cách linh động:
RoundedPolygon.getBounds() xác định một hàm mở rộng trên lớp RoundedPolygon để tính toán các giới hạn của hàm đó.
Lớp RoundedPolygonShape triển khai giao diện Shape, cho phép bạn xác định một hình dạng tuỳ chỉnh (đa giác bo tròn) trong Jetpack Compose.
Hình dạng này sử dụng Matrix để quản lý các thao tác điều chỉnh tỷ lệ và dịch để kết xuất linh hoạt.
Hàm createOutline() lấy một đối tượng RoundedPolygon, điều chỉnh theo tỷ lệ và dịch đối tượng đó để vừa với một kích thước nhất định, đồng thời trả về một đối tượng Outline mô tả hình dạng cuối cùng cần vẽ.
Cắt hình ảnh thành một hình dạng
Mã sau đây sẽ cắt hình ảnh thành hình lục giác và thêm một bóng đổ tinh tế để tạo cảm giác chiều sâu:
Các đối tượng RoundedPolygon và RoundedPolygonShape được dùng để xác định và áp dụng hình lục giác cho hình ảnh.
Mã này sử dụng graphicsLayer để thêm bóng dựa trên độ cao vào hình ảnh.
Điều này tạo ra cảm giác về chiều sâu và sự tách biệt về hình ảnh với nền.
Việc sử dụng các khối remember giúp tối ưu hoá hiệu suất bằng cách đảm bảo rằng các định nghĩa về hình dạng và cắt chỉ được tính toán một lần và được ghi nhớ để kết hợp lại giao diện người dùng sau này.
Kết quả
Hình 1. Hình dạng tuỳ chỉnh được áp dụng dưới dạng đoạn video.
Các bộ sưu tập chứa hướng dẫn này
Hướng dẫn này là một phần của các bộ sưu tập Hướng dẫn nhanh được tuyển chọn này, bao gồm các mục tiêu phát triển Android rộng hơn:
Hiển thị hình ảnh
Khám phá các kỹ thuật sử dụng hình ảnh tươi sáng, bắt mắt để mang lại giao diện đẹp mắt cho ứng dụng Android.
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2025-02-06 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2025-02-06 UTC."],[],[],null,["# Display an image clipped to a shape\n\n\u003cbr /\u003e\n\nYou can fit an image to a clipped shape, and draw shadows around the perimeter\nof the shape to impart a three-dimensional feel. This technique is useful for\ncreating designs such as avatars and product thumbnails, or displaying\nlogos with custom shapes.\n\nTo display an image clipped to a shape, you must do the following:\n\n- Create the shape.\n- Clip the image to the shape.\n\nVersion compatibility\n---------------------\n\nThis implementation requires that your project minSDK be set to API level 21 or\nhigher.\n\n### Dependencies\n\n### Kotlin\n\n\u003cbr /\u003e\n\n```kotlin\n implementation(platform(\"androidx.compose:compose-bom:2025.08.00\"))\n implementation(\"androidx.graphics:graphics-shapes:1.0.0-alpha05\")\n \n```\n\n\u003cbr /\u003e\n\n### Groovy\n\n\u003cbr /\u003e\n\n```groovy\n implementation platform('androidx.compose:compose-bom:2025.08.00')\n implementation 'androidx.graphics:graphics-shapes:1.0.0-alpha05'\n \n```\n\n\u003cbr /\u003e\n\nCreate a shape\n--------------\n\nThe following code creates a custom shape that can dynamically draw and render\na rounded polygon:\n\n\n```kotlin\nfun RoundedPolygon.getBounds() = calculateBounds().let { Rect(it[0], it[1], it[2], it[3]) }\nclass RoundedPolygonShape(\n private val polygon: RoundedPolygon,\n private var matrix: Matrix = Matrix()\n) : Shape {\n private var path = Path()\n override fun createOutline(\n size: Size,\n layoutDirection: LayoutDirection,\n density: Density\n ): Outline {\n path.rewind()\n path = polygon.toPath().asComposePath()\n matrix.reset()\n val bounds = polygon.getBounds()\n val maxDimension = max(bounds.width, bounds.height)\n matrix.scale(size.width / maxDimension, size.height / maxDimension)\n matrix.translate(-bounds.left, -bounds.top)\n\n path.transform(matrix)\n return Outline.Generic(path)\n }\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/graphics/ShapesSnippets.kt#L353-L375\n```\n\n\u003cbr /\u003e\n\n### Key points about the code\n\n- `RoundedPolygon.getBounds()` defines an extension function on the [`RoundedPolygon`](/reference/kotlin/androidx/graphics/shapes/RoundedPolygon) class to calculate its bounds.\n- The `RoundedPolygonShape` class implements the [`Shape`](/reference/kotlin/androidx/compose/ui/graphics/Shape) interface, allowing you to define a custom shape (a rounded polygon) in Jetpack Compose.\n- The shape uses a [`Matrix`](/reference/kotlin/androidx/compose/ui/graphics/Matrix) to manage scaling and translation operations for flexible rendering.\n- The `createOutline()` function takes a `RoundedPolygon` object, scales and translates it to fit within a given size, and returns an [`Outline`](/reference/kotlin/androidx/compose/ui/graphics/Outline) object that describes the final shape to be drawn.\n\nClip the image to a shape\n-------------------------\n\nThe following code crops the image to a hexagon, and adds a subtle drop\nshadow to provide a sense of depth:\n\n\n```kotlin\nval hexagon = remember {\n RoundedPolygon(\n 6,\n rounding = CornerRounding(0.2f)\n )\n}\nval clip = remember(hexagon) {\n RoundedPolygonShape(polygon = hexagon)\n}\nBox(\n modifier = Modifier\n .clip(clip)\n .background(MaterialTheme.colorScheme.secondary)\n .size(200.dp)\n) {\n Text(\n \"Hello Compose\",\n color = MaterialTheme.colorScheme.onSecondary,\n modifier = Modifier.align(Alignment.Center)\n )\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/graphics/ShapesSnippets.kt#L382-L402\n```\n\n\u003cbr /\u003e\n\n### Key points about the code\n\n- The `RoundedPolygon` and `RoundedPolygonShape` objects are used to define and apply a hexagonal shape to the image.\n- The code uses [`graphicsLayer`](/reference/kotlin/androidx/compose/ui/graphics/package-summary#(androidx.compose.ui.Modifier).graphicsLayer(kotlin.Function1)) to add an elevation-based shadow to the image. This creates a sense of depth and visual separation from the background.\n- The use of [`remember`](/reference/kotlin/androidx/compose/runtime/package-summary#remember(kotlin.Function0)) blocks optimizes performance by ensuring that the shape and clipping definitions are calculated only once and remembered for later recompositions of the UI.\n\nResults\n-------\n\n**Figure 1.** Custom shape applied as clip.\n\nCollections that contain this guide\n-----------------------------------\n\nThis guide is part of these curated Quick Guide collections that cover\nbroader Android development goals: \n\n### Display images\n\nDiscover techniques for using bright, engaging visuals to give your Android app a beautiful look and feel. \n[Quick guide collection](/develop/ui/compose/quick-guides/collections/display-images) \n\nHave questions or feedback\n--------------------------\n\nGo to our frequently asked questions page and learn about quick guides or reach out and let us know your thoughts. \n[Go to FAQ](/quick-guides/faq) [Leave feedback](https://issuetracker.google.com/issues/new?component=1573691&template=1993320)"]]