DEV Community

Cover image for QRKit — QRCode Generator in Compose Multiplatform for Android and iOS
Mobile innovation Network
Mobile innovation Network

Posted on

QRKit — QRCode Generator in Compose Multiplatform for Android and iOS

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") } 
Enter fullscreen mode Exit fullscreen mode

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 -> } ) 
Enter fullscreen mode Exit fullscreen mode
  • 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) } } } 
Enter fullscreen mode Exit fullscreen mode
@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) ) } } } 
Enter fullscreen mode Exit fullscreen mode
@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) ) } } } 
Enter fullscreen mode Exit fullscreen mode

Final Demo:

QRKit

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)