a QR代码(快速安息代码)是一种条形码,表示为黑白正方形的矩阵。 QR码使表示文本,例如以图像格式表示文本,例如电话号码,URL和其他信息。
在Jetpack Compose(Google的新的UI工具包用于Android应用程序)中,创建一个可用于渲染可以绘制到指定边界区域的映像和UI元素的实例非常容易。默认情况下,撰写中有许多Painter
子类,但我们将重点放在BitmapPainter
上。
添加Zxing核心依赖性
第一步是生成将在我们的UI中渲染的QR代码位图映像。为此,我们将使用Google使用koude3库。 Zxing是用于Java和Android的开源条形码扫描LIBARY。将依赖关系添加到模块级别(在一个简单的项目中,这将是应用程序)build.gradle
file:
dependencies {
...
implementation "com.google.zxing:core:3.5.1"
}
定义画家功能
让我们定义一种特殊类型的可复合函数,该功能返回值并具有骆驼壳命名,而不是我们通常的可复合函数,该功能用 pascalcase naming和返回无值(单位)。这将返回将传递给我们的Image
综合函数时将渲染QR码的BitmapPainter
:
@Composable
fun rememberQrBitmapPainter(
content: String,
size: Dp = 150.dp,
padding: Dp = 0.dp
): BitmapPainter {
return BitmapPainter()
}
我们的rememberQrBitmapPainter
采用了一个content: String
,该content: String
表示我们要在QR代码,size:Dp
中编码的文本值,该QR代表QR的大小(宽度x高),该QR指定为设备无关的像素值(以确保我们具有锋利在不同像素密度的不同设备上的图像)和padding:Dp
表示我们想要围绕生成的代码的空间边框的数量。填充设置为默认值为0,以覆盖/删除ZXing库生成QR位图时添加的默认填充。
让我们在我们的功能中添加4个新变量;
density
使用LocalDensity
local来检索设备的当前屏幕密度信息。 Density
接口提供了有用的扩展功能,用于执行简单操作,例如获取与我们之前指定的.dp
值相当的设备像素等效。
sizePx
和paddingPx
变量分别表示大小和填充的像素。
bitmap
可变状态变量保存QR码的位图。为了防止在状态更改(重组)重新绘制UI时,我们的位图被重新计算,我们将其用内容键将其包裹起来。内容密钥允许我们在QR包含更改的值时重新计算位图。
@Composable
fun rememberQrBitmapPainter(
content: String,
size: Dp = 150.dp,
padding: Dp = 0.dp
): BitmapPainter {
val density = LocalDensity.current
val sizePx = with(density) { size.roundToPx() }
val paddingPx = with(density) { padding.roundToPx() }
var bitmap by remember(content) {
mutableStateOf<Bitmap?>(null)
}
return BitmapPainter()
}
QR代码是一个矩阵,由多个像素组成,如果在UI线程上计算的值,则可能导致您的UI口吃或挂起;因此,我们将使用LaunchedEffect
和IO
CoroutineDispatcher
来卸载UI线程QR码的位图所需的工作:
LaunchedEffect(bitmap) {
if (bitmap != null) return@LaunchedEffect
launch(Dispatchers.IO) {
val qrCodeWriter = QRCodeWriter()
val encodeHints = mutableMapOf<EncodeHintType, Any?>()
.apply {
this[EncodeHintType.MARGIN] = paddingPx
}
val bitmapMatrix = try {
qrCodeWriter.encode(
content, BarcodeFormat.QR_CODE,
sizePx, sizePx, encodeHints
)
} catch (ex: WriterException) {
null
}
}
}
在这里,我们创建了一个QRCodeWriter
实例,该实例将用于编码QR。 encodeHints
变量是EncodeHintType
到值的映射,用于配置QRCodeWriter
。通过编码内容字符串并指定QR的高度和宽度来创建bitmapMatrix
。
我们需要从bitmapmatrix创建一个位图,并为每个像素(白色或黑色)设置颜色:
val matrixWidth = bitmapMatrix?.width ?: sizePx
val matrixHeight = bitmapMatrix?.height ?: sizePx
val newBitmap = Bitmap.createBitmap(
bitmapMatrix?.width ?: sizePx,
bitmapMatrix?.height ?: sizePx,
Bitmap.Config.ARGB_8888,
)
for (x in 0 until matrixWidth) {
for (y in 0 until matrixHeight) {
val shouldColorPixel = bitmapMatrix?.get(x, y) ?: false
val pixelColor = if (shouldColorPixel) Color.BLACK else Color.WHITE
newBitmap.setPixel(x, y, pixelColor)
}
}
bitmap = newBitmap
在我们的最后一步中,我们返回一个BitmapPainter
的实例,其中计算出的位图作为参数传递。如果尚未计算位图,我们将通过透明颜色的空位图相等的位图。然后使用Bitmap.asImagePainter()
扩展功能将位图转换为图像位图。
return remember(bitmap) {
val currentBitmap = bitmap ?: Bitmap.createBitmap(
sizePx, sizePx,
Bitmap.Config.ARGB_8888,
).apply { eraseColor(Color.TRANSPARENT) }
BitmapPainter(currentBitmap.asImageBitmap())
}
您将如何使用它:
Image(
painter = rememberQrBitmapPainter("https://dev.to"),
contentDescription = "DEV Communit Code",
contentScale = ContentScale.FillBounds,
modifier = Modifier.size(135.dp),
)
将所有我们得到的一切都放在一起:QRPainter.kt
希望您发现这篇文章有用,并感谢您的阅读。