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.
Trong Compose, đối tượng Painter được dùng để thể hiện nội dung nào đó có thể vẽ (thay thế cho các API Drawable được xác định trong Android) và tạo tác động đến hoạt động đo lường cùng với bố cục của thành phần kết hợp tương ứng đang sử dụng đối tượng đó. BitmapPainter lấy ImageBitmap có khả năng vẽ Bitmap trên màn hình.
Đối với hầu hết các trường hợp sử dụng, việc sử dụng painterResource() ở trên sẽ trả về đúng Painter cho thành phần (tức là BitmapPainter hoặc VectorPainter). Để biết thêm thông tin về sự khác biệt giữa 2 loại này, hãy đọc phần ImageBitmap so với ImageVector.
Painter khác với DrawModifier ở chỗ khi được dùng sẽ vẽ một cách nghiêm ngặt trong giới hạn được cấp và hoàn toàn không tác động đến hoạt động đo lường hoặc bố cục của thành phần kết hợp.
Để tạo một Painter tuỳ chỉnh, hãy mở rộng lớp Painter và triển khai phương thức onDraw. Phương thức này cho phép truy cập vào DrawScope để vẽ các đồ hoạ tuỳ chỉnh. Bạn cũng có thể ghi đè intrinsicSize dùng để tạo tác động đến Thành phần kết hợp có ở trong:
classOverlayImagePainterconstructor(privatevalimage:ImageBitmap,privatevalimageOverlay:ImageBitmap,privatevalsrcOffset:IntOffset=IntOffset.Zero,privatevalsrcSize:IntSize=IntSize(image.width,image.height),privatevaloverlaySize:IntSize=IntSize(imageOverlay.width,imageOverlay.height)):Painter(){privatevalsize:IntSize=validateSize(srcOffset,srcSize)overridefunDrawScope.onDraw(){// draw the first image without any blend modedrawImage(image,srcOffset,srcSize,dstSize=IntSize(this@onDraw.size.width.roundToInt(),this@onDraw.size.height.roundToInt()))// draw the second image with an Overlay blend mode to blend the two togetherdrawImage(imageOverlay,srcOffset,overlaySize,dstSize=IntSize(this@onDraw.size.width.roundToInt(),this@onDraw.size.height.roundToInt()),blendMode=BlendMode.Overlay)}/** * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height */overridevalintrinsicSize:Sizeget()=size.toSize()privatefunvalidateSize(srcOffset:IntOffset,srcSize:IntSize):IntSize{require(srcOffset.x>=0&&
srcOffset.y>=0&&
srcSize.width>=0&&
srcSize.height>=0&&
srcSize.width<=image.width&&
srcSize.height<=image.height)returnsrcSize}}
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-08-28 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-08-28 UTC."],[],[],null,["In Compose, a `Painter` object is used to represent something that can be drawn\n(a replacement to the `Drawable` APIs defined in Android) and influence\nmeasurement and layout of the corresponding composable that is using it . A\n`BitmapPainter` takes an `ImageBitmap` that can draw a `Bitmap` on screen.\n\nFor most use cases, using the `painterResource()` above returns the correct\npainter for the asset (i.e. `BitmapPainter` or `VectorPainter`). For more\ninformation on the differences between the two - read the [ImageBitmap vs ImageVector](/develop/ui/compose/graphics/images/compare) section.\n\nA `Painter` is different from a `DrawModifier`, which strictly draws within the\nbounds that are given to it and has no influence on the measurement or layout of\nthe composable.\n\nTo create a custom painter, extend the `Painter` class, and implement the\n`onDraw` method, which allows access to the `DrawScope` to draw custom\ngraphics. You can also override the `intrinsicSize`, which will be used to\ninfluence the Composable that it is contained in:\n\n\n```kotlin\nclass OverlayImagePainter constructor(\n private val image: ImageBitmap,\n private val imageOverlay: ImageBitmap,\n private val srcOffset: IntOffset = IntOffset.Zero,\n private val srcSize: IntSize = IntSize(image.width, image.height),\n private val overlaySize: IntSize = IntSize(imageOverlay.width, imageOverlay.height)\n) : Painter() {\n\n private val size: IntSize = validateSize(srcOffset, srcSize)\n override fun DrawScope.onDraw() {\n // draw the first image without any blend mode\n drawImage(\n image,\n srcOffset,\n srcSize,\n dstSize = IntSize(\n this@onDraw.size.width.roundToInt(),\n this@onDraw.size.height.roundToInt()\n )\n )\n // draw the second image with an Overlay blend mode to blend the two together\n drawImage(\n imageOverlay,\n srcOffset,\n overlaySize,\n dstSize = IntSize(\n this@onDraw.size.width.roundToInt(),\n this@onDraw.size.height.roundToInt()\n ),\n blendMode = BlendMode.Overlay\n )\n }\n\n /**\n * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height\n */\n override val intrinsicSize: Size get() = size.toSize()\n\n private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize {\n require(\n srcOffset.x \u003e= 0 &&\n srcOffset.y \u003e= 0 &&\n srcSize.width \u003e= 0 &&\n srcSize.height \u003e= 0 &&\n srcSize.width \u003c= image.width &&\n srcSize.height \u003c= image.height\n )\n return srcSize\n }\n}https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/images/CustomPainterSnippets.kt#L79-L128\n```\n\n\u003cbr /\u003e\n\nNow that we have our custom `Painter`, we can overlay any image on top of our\nsource image as follows:\n\n\n```kotlin\nval rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow)\nval dogImage = ImageBitmap.imageResource(id = R.drawable.dog)\nval customPainter = remember {\n OverlayImagePainter(dogImage, rainbowImage)\n}\nImage(\n painter = customPainter,\n contentDescription = stringResource(id = R.string.dog_content_description),\n contentScale = ContentScale.Crop,\n modifier = Modifier.wrapContentSize()\n)https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/images/CustomPainterSnippets.kt#L64-L74\n```\n\n\u003cbr /\u003e\n\nThe output of combining the two images with a custom painter can be seen below:\n**Figure 1**: Custom Painter that overlays two images on top of each other\n\nA custom painter can also be used with the [`Modifier.paint(customPainter)`](/reference/kotlin/androidx/compose/ui/draw/package-summary#(androidx.compose.ui.Modifier).paint(androidx.compose.ui.graphics.painter.Painter,kotlin.Boolean,androidx.compose.ui.Alignment,androidx.compose.ui.layout.ContentScale,kotlin.Float,androidx.compose.ui.graphics.ColorFilter))\nto draw the content to a composable as follows:\n\n\n```kotlin\nval rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow)\nval dogImage = ImageBitmap.imageResource(id = R.drawable.dog)\nval customPainter = remember {\n OverlayImagePainter(dogImage, rainbowImage)\n}\nBox(\n modifier =\n Modifier.background(color = Color.Gray)\n .padding(30.dp)\n .background(color = Color.Yellow)\n .paint(customPainter)\n) { /** intentionally empty **/ }https://github.com/android/snippets/blob/dd30aee903e8c247786c064faab1a9ca8d10b46e/compose/snippets/src/main/java/com/example/compose/snippets/images/CustomPainterSnippets.kt#L135-L146\n```\n\n\u003cbr /\u003e\n\n| **Note:** The above custom Painter can also be implemented using a `DrawModifier`. If you need to influence measurement or layout, then you should use a `Painter`. If you are only expecting to render in the bounds you are given, then you should use a `DrawModifier` instead.\n\nRecommended for you\n\n- Note: link text is displayed when JavaScript is off\n- [ImageBitmap vs ImageVector {:#bitmap-vs-vector}](/develop/ui/compose/graphics/images/compare)\n- [Graphics in Compose](/develop/ui/compose/graphics/draw/overview)\n- [Loading images {:#loading-images}](/develop/ui/compose/graphics/images/loading)"]]