QRKit is a Kotlin Multiplatform library for Qr Generator in your Android or iOS App.
Installation
Add the dependency to your build.gradle.kts
file:
commonMain.dependencies {
implementation("network.chaintech:qr-kit:1.0.2")
}
Example
QRCodeImage(
url: String,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null,
filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
onSuccess: (ImageBitmap) -> Unit = { qrImage -> },
onFailure: (String) -> Unit = { message -> }
)
-
url
: The URL of the QR code image to be displayed. -
contentDescription
: A textual description of the image content for accessibility purposes. It's optional. -
modifier
: Modifier for modifying the layout of the QR code image. -
alignment
: Alignment of the QR code image within its layout bounds. Default is Alignment.Center. -
contentScale
: The scale strategy for fitting the QR code image content within its layout bounds. Default is ContentScale.Fit. -
alpha
: The opacity of the QR code image, ranging from 0.0 (fully transparent) to 1.0 (fully opaque). Default is DefaultAlpha. -
colorFilter
: A color filter to apply to the QR code image. Default is null. -
filterQuality
: The quality of the filtering applied to the QR code image. Default is DrawScope.DefaultFilterQuality. -
onSuccess
: Callback invoked when the QR code image is successfully loaded and decoded, passing the decoded ImageBitmap as a parameter. -
onFailure
: Callback invoked when there's a failure during loading or decoding the QR code image, passing an error message as a parameter.
Usage
@Composable
fun QrGeneratorCompose(paddingValues: PaddingValues) {
val scope = rememberCoroutineScope()
var inputText by rememberSaveable { mutableStateOf("") }
var isInputTextError by rememberSaveable { mutableStateOf(false) }
val generatedQRCode = remember { mutableStateOf<ImageBitmap?>(null) }
val focusManager = LocalFocusManager.current
val snackBarHostState = LocalSnackBarHostState.current
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(horizontal = 16.dp)
.padding(top = 22.dp)
.verticalScroll(rememberScrollState())
) {
QRCodeImage(
url = "https://www.google.com/",
contentScale = ContentScale.Fit,
contentDescription = "QR Code",
modifier = Modifier
.size(150.dp),
onSuccess = { qrImage ->
},
onFailure = {
scope.launch {
snackBarHostState.showSnackbar("Something went wrong")
}
}
)
OutlinedTextField(
value = inputText,
onValueChange = {
inputText = it
isInputTextError = inputText.isBlank()
},
label = { Text("Please enter text", style = MaterialTheme.typography.titleMedium) },
textStyle = MaterialTheme.typography.bodyLarge,
singleLine = false,
isError = isInputTextError,
modifier = Modifier.padding(top = 14.dp).fillMaxWidth(),
shape = RoundedCornerShape(10),
trailingIcon = {
if (isInputTextError) {
Icon(
imageVector = Icons.Default.Error,
contentDescription = "Error",
tint = Color.Red
)
}
}
)
Spacer(modifier = Modifier.height(22.dp))
Button(
onClick = {
if (inputText.isBlank()) {
isInputTextError = true
return@Button
} else {
focusManager.clearFocus()
generateQrCode(
inputText,
onSuccess = { info, qrCode ->
generatedQRCode.value = qrCode
},
onFailure = {
scope.launch {
snackBarHostState.showSnackbar("Something went wrong")
}
}
)
}
},
modifier = Modifier
.fillMaxWidth()
.height(54.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF007AFF)),
shape = RoundedCornerShape(25)
) {
Text(
text = "Generate code",
style = MaterialTheme.typography.bodyLarge,
color = Color.White
)
}
generatedQRCode.value?.let { qrCode ->
QRCodeViewer(qrCode)
}
}
}
@Composable
fun QRCodeViewer(qrCode: ImageBitmap) {
var isLoading by rememberSaveable { mutableStateOf(true) }
LaunchedEffect(Unit) {
delay(500)
isLoading = false
}
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxSize()
.padding(vertical = 22.dp),
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.background(Color.White)
.border(BorderStroke(3.dp, Color.Black))
.size(250.dp)
) {
if (isLoading) {
QRCodeShimmer()
return@Column
}
Image(
bitmap = qrCode,
contentScale = ContentScale.Fit,
contentDescription = "QR Code",
modifier = Modifier
.fillMaxSize(1f)
)
}
}
}
@Composable
fun QRCodeShimmer() {
val shimmerColorShades = listOf(
Color.Gray.copy(0.5f),
Color.LightGray.copy(0.2f),
Color.Gray.copy(0.5f),
)
val transition = rememberInfiniteTransition()
val transitionAnim by transition.animateFloat(
initialValue = 0f,
targetValue = 1000f,
animationSpec = infiniteRepeatable(
tween(durationMillis = 1200, easing = FastOutSlowInEasing),
RepeatMode.Reverse
)
)
val brush = Brush.linearGradient(
colors = shimmerColorShades,
start = Offset(10f, 10f),
end = Offset(transitionAnim, transitionAnim)
)
Surface(
color = Color.Transparent,
modifier = Modifier.alpha(.3f)
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.size(300.dp)
) {
Spacer(
modifier = Modifier
.fillMaxSize()
.background(brush = brush)
)
Spacer(
modifier = Modifier
.fillMaxSize(.8f)
.background(brush = brush)
)
}
}
}
Final Demo:
Conclusion
Integrating a QR code generator library enhances functionality, streamlines processes, and improves user experience in your application.
https://github.com/ChainTechNetwork/QRKitComposeMultiplatform.git
Happy coding ❤
Connect with us 👇
Top comments (0)