Android Compose - 如何平铺/重复位图/矢量?
Posted
技术标签:
【中文标题】Android Compose - 如何平铺/重复位图/矢量?【英文标题】:Android Compose - How to tile/repeat a bitmap/vector? 【发布时间】:2021-08-04 17:17:57 【问题描述】:什么是平铺图像以用小图案填充背景的 android Compose 方法?
没有旋转的位图的天真方法可能是这样的:
@Composable
fun TileImage()
val pattern = ImageBitmap.imageResource(R.drawable.pattern_bitmap)
Canvas(modifier = Modifier.fillMaxSize())
// rotate(degrees = -15f) // The rotation does not produce the desired effect
val totalWidth = size.width / pattern.width
val totalHeight = size.height / pattern.height
var x = 0f
var y = 0f
for (i in 0..totalHeight.toInt())
y = (i * pattern.height).toFloat()
for (j in 0..totalWidth.toInt())
x = (j * pattern.width).toFloat()
drawImage(
pattern,
colorFilter = giftColorFilter,
topLeft = Offset(x, y)
)
//
在 Android XML 中,您可以轻松创建 XML 以重复位图
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/pattern_bitmap"
android:tileMode="repeat" />
或者,如果您需要平铺矢量,您可以使用自定义 Drawable 类来实现您的目标
TileDrawable(AppCompatResources.getDrawable(context, R.drawable.pattern_vector), Shader.TileMode.REPEAT)
class TileDrawable(drawable: Drawable, tileMode: Shader.TileMode, private val angle: Float? = null) : Drawable()
private val paint: Paint = Paint().apply
shader = BitmapShader(getBitmap(drawable), tileMode, tileMode)
override fun draw(canvas: Canvas)
angle?.let
canvas.rotate(it)
canvas.drawPaint(paint)
override fun setAlpha(alpha: Int)
paint.alpha = alpha
override fun getOpacity() = PixelFormat.TRANSLUCENT
override fun setColorFilter(colorFilter: ColorFilter?)
paint.colorFilter = colorFilter
private fun getBitmap(drawable: Drawable): Bitmap
if (drawable is BitmapDrawable)
return drawable.bitmap
val bmp = Bitmap.createBitmap(
drawable.intrinsicWidth, drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888
)
val c = Canvas(bmp)
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
drawable.draw(c)
return bmp
【问题讨论】:
【参考方案1】:如果你想使用原生画布,你可以在 jetpack compose 中执行类似的操作。
Canvas(
modifier = Modifier
.fillMaxSize()
)
val paint = Paint().asFrameworkPaint().apply
isAntiAlias = true
shader = ImageShader(pattern, TileMode.Repeated, TileMode.Repeated)
drawIntoCanvas
it.nativeCanvas.drawPaint(paint)
paint.reset()
如果您想将重复限制在某个高度和宽度,您可以在画布中使用剪辑修饰符,如下所示,否则它将填满整个屏幕。
Canvas(
modifier = Modifier
.width(300.dp)
.height(200.dp)
.clip(RectangleShape)
)
----
【讨论】:
很好,现在旋转也很好用。向量呢? 您可以先将矢量转换为 imageBitmap。我认为它应该工作。 val imageBitmap = ResourcesCompat.getDrawable(resources, R.drawable.ic_friends_24, null)!!.toBitmap().asImageBitmap() 有一种更好的方法可以将矢量转换为 imageBitmap:ImageBitmap.imageResource(id = R.drawable.your_drawable)以上是关于Android Compose - 如何平铺/重复位图/矢量?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Jetpack Compose UI 在 Android 上正确跟踪屏幕视图?