DEV Community

Cover image for ScreenCapture -Compose Multiplatform(KMP)
Mobile innovation Network
Mobile innovation Network

Posted on • Updated on

ScreenCapture -Compose Multiplatform(KMP)

ScreenCapture is a Compose Multiplatform library for capturing screens in your Android or iOS App.

ScreenCapture

Installation

Add the dependency to your build.gradle.kts file:

commonMain.dependencies {
    implementation("network.chaintech:compose-multiplatform-screen-capture:1.0.2")
}
Enter fullscreen mode Exit fullscreen mode

Usage

Android

  • Include this in your AndroidManifest.xml:
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="network.chaintech.cmp.screenshot.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
Enter fullscreen mode Exit fullscreen mode
  • Create file_paths.xml in androidMain->res->xml and add the following code:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path
        name="screen_shots"
        path="share_images" />
    <external-path
        name="external_files"
        path="." />
</paths>
Enter fullscreen mode Exit fullscreen mode
  • Add the following line in onCreate of your Activity class:
class AppActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        AppContext.apply { set(this@AppActivity) }
        ...
    }
}
Enter fullscreen mode Exit fullscreen mode

Composable Usage

@Composable
internal fun App() = AppTheme {
    PaymentReceived()
}

@Composable
fun PaymentReceived() {
    val captureController = rememberScreenCaptureController()
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0xFF004DEF))
    ) {
        Row(
            modifier = Modifier.padding(top = 20.dp).statusBarsPadding(),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Spacer(modifier = Modifier.weight(1f))
            Icon(
                Icons.Filled.Share,
                "Share",
                modifier = Modifier.padding(end = 12.dp).size(28.dp)
                    .clickable { captureController.capture() },
                tint = Color.White
            )
        }

        ScreenCaptureComposable(
            modifier = Modifier,
            screenCaptureController = captureController,
            shareImage = true,
            onCaptured = { img, throwable ->

            }
        ) {
            AppTheme {
                Column(modifier = Modifier.background(Color.White)) {
                    PaymentReceivedView()
                }
            }
        }
    }
}

@Composable
fun ColumnScope.PaymentReceivedView() {
    Box(modifier = Modifier.fillMaxWidth()) {
        Box(modifier = Modifier.height(200.dp).fillMaxWidth().background(Color(0xFF004DEF))) {
            Text(
                text = "Invoice",
                style = TextStyle(fontSize = 20.sp, color = Color.White),
                fontWeight = FontWeight.Medium,
                modifier = Modifier.padding(top = 18.dp).align(Alignment.TopCenter)
            )
        }
        Card(
            modifier = Modifier
                .padding(top = 96.dp, start = 16.dp, end = 16.dp, bottom = 30.dp)
                .fillMaxWidth(),
            colors = CardDefaults.cardColors(Color.White),
            shape = RoundedCornerShape(6.dp),
            elevation = CardDefaults.cardElevation(2.dp)
        ) {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
            ) {
                Text(
                    text = "Money Transfer",
                    style = TextStyle(fontSize = 20.sp, color = Color.Black),
                    fontWeight = FontWeight.Medium,
                    modifier = Modifier.padding(top = 50.dp).align(Alignment.CenterHorizontally)
                )
                Text(
                    text = "Powered by MobiKwik",
                    style = TextStyle(fontSize = 20.sp, color = Color.Black),
                    fontWeight = FontWeight.Medium,
                    modifier = Modifier.padding(top = 4.dp).align(Alignment.CenterHorizontally)
                )

                Column(
                    modifier = Modifier
                        .fillMaxWidth(0.8f)
                        .padding(top = 16.dp)
                        .background(Color(0xFFF7F7F7), RoundedCornerShape(8.dp))
                        .padding(bottom = 10.dp).align(Alignment.CenterHorizontally),
                ) {
                    Text(
                        text = "Order ID: OMK25e9ef4ed5005544",
                        style = TextStyle(fontSize = 14.sp, color = Color.Gray),
                        modifier = Modifier.padding(top = 10.dp, start = 16.dp, end = 16.dp)
                    )

                    DashedLine(modifier = Modifier.padding(top = 10.dp).height(2.dp).fillMaxWidth())

                    Text(
                        text = "UPI Transaction ID: 4320692331397",
                        style = TextStyle(fontSize = 14.sp, color = Color.Gray),
                        modifier = Modifier.padding(top = 10.dp, start = 16.dp, end = 16.dp)
                    )
                }
                Text(
                    text = "Fri, 04 Feb 2024, 8:12 pm",
                    style = TextStyle(fontSize = 14.sp, color = Color.Gray),
                    modifier = Modifier.padding(top = 16.dp, bottom = 16.dp)
                        .align(Alignment.CenterHorizontally)
                )
            }
        }
        Column(modifier = Modifier.fillMaxWidth()) {
            Card(
                modifier = Modifier
                    .padding(top = 66.dp)
                    .size(60.dp)
                    .align(Alignment.CenterHorizontally),
                colors = CardDefaults.cardColors(Color.White),
                shape = CircleShape,
                elevation = CardDefaults.cardElevation(0.dp)
            ) {
                Box(
                    modifier = Modifier
                        .padding(3.dp)
                        .fillMaxSize()
                        .border(2.dp, Color(0xFF004DEF), CircleShape)
                        .clip(CircleShape)
                        .align(Alignment.CenterHorizontally)
                ) {
                    Icon(
                        Icons.Filled.Done,
                        "Share",
                        modifier = Modifier.size(36.dp).align(Alignment.Center),
                        tint = Color.Green
                    )
                }
            }
        }
    }
    Column(
        modifier = Modifier.background(Color(0xFFE6EBE5))
            .padding(horizontal = 14.dp, vertical = 18.dp)
    ) {
        Row(modifier = Modifier.fillMaxWidth()) {
            Text(
                text = "Total Amount Paid",
                style = TextStyle(fontSize = 20.sp, color = Color.Black),
                fontWeight = FontWeight.Medium,
                modifier = Modifier
            )
            Spacer(modifier = Modifier.width(1.dp).weight(1f))
            Text(
                text = "₹395",
                style = TextStyle(fontSize = 20.sp, color = Color.Black),
                fontWeight = FontWeight.Medium,
                modifier = Modifier
            )
        }
        Text(
            text = "Paid from UPI: ₹395",
            style = TextStyle(fontSize = 14.sp, color = Color.Gray),
            modifier = Modifier.padding(top = 8.dp)
        )
    }

    Text(
        text = "Billed To",
        style = TextStyle(fontSize = 16.sp, color = Color.Black),
        modifier = Modifier.padding(top = 20.dp, start = 14.dp, end = 14.dp)
    )

    Row(modifier = Modifier.padding(top = 8.dp, start = 14.dp, end = 14.dp).fillMaxWidth()) {
        Text(
            text = "Name",
            style = TextStyle(fontSize = 16.sp, color = Color.Gray),
            modifier = Modifier
        )
        Spacer(modifier = Modifier.width(1.dp).weight(1f))
        Text(
            text = "Robert Jhon Castillo",
            style = TextStyle(fontSize = 16.sp, color = Color.Black),
            modifier = Modifier
        )
    }
    Row(modifier = Modifier.padding(top = 8.dp, start = 14.dp, end = 14.dp).fillMaxWidth()) {
        Text(
            text = "Mobile No.",
            style = TextStyle(fontSize = 16.sp, color = Color.Gray),
            modifier = Modifier
        )
        Spacer(modifier = Modifier.width(1.dp).weight(1f))
        Text(
            text = "7896554456",
            style = TextStyle(fontSize = 16.sp, color = Color.Black),
            modifier = Modifier
        )
    }
    Row(modifier = Modifier.padding(top = 8.dp, start = 14.dp, end = 14.dp).fillMaxWidth()) {
        Text(
            text = "VPA",
            style = TextStyle(fontSize = 16.sp, color = Color.Gray),
            modifier = Modifier
        )
        Spacer(modifier = Modifier.width(1.dp).weight(1f))
        Text(
            text = "7896554456@ikwik",
            style = TextStyle(fontSize = 16.sp, color = Color.Black),
            modifier = Modifier
        )
    }

    Text(
        text = "Received By",
        style = TextStyle(fontSize = 16.sp, color = Color.Black),
        modifier = Modifier.padding(top = 20.dp, start = 14.dp, end = 14.dp)
    )

    Row(modifier = Modifier.padding(top = 8.dp, start = 14.dp, end = 14.dp).fillMaxWidth()) {
        Text(
            text = "Name",
            style = TextStyle(fontSize = 16.sp, color = Color.Gray),
            modifier = Modifier
        )
        Spacer(modifier = Modifier.width(1.dp).weight(1f))
        Text(
            text = "Robert Jhon Castillo",
            style = TextStyle(fontSize = 16.sp, color = Color.Black),
            modifier = Modifier
        )
    }
    Row(modifier = Modifier.padding(top = 8.dp, start = 14.dp, end = 14.dp).fillMaxWidth()) {
        Text(
            text = "Mobile No.",
            style = TextStyle(fontSize = 16.sp, color = Color.Gray),
            modifier = Modifier
        )
        Spacer(modifier = Modifier.width(1.dp).weight(1f))
        Text(
            text = "NA",
            style = TextStyle(fontSize = 16.sp, color = Color.Black),
            modifier = Modifier
        )
    }
    Row(modifier = Modifier.padding(top = 8.dp, start = 14.dp, end = 14.dp).fillMaxWidth()) {
        Text(
            text = "VPA",
            style = TextStyle(fontSize = 16.sp, color = Color.Gray),
            modifier = Modifier
        )
        Spacer(modifier = Modifier.width(1.dp).weight(1f))
        Text(
            text = "paytm-jiomobility@paytm",
            style = TextStyle(fontSize = 16.sp, color = Color.Black),
            modifier = Modifier
        )
    }
    Image(
        modifier = Modifier
            .padding(top = 26.dp, bottom = 40.dp)
            .size(90.dp)
            .align(Alignment.CenterHorizontally),
        painter = painterResource(Res.drawable.qr_code),
        contentDescription = null,
        contentScale = ContentScale.Crop
    )
}

@Composable
private fun DashedLine(modifier: Modifier) {
    val pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
    Canvas(modifier) {

        drawLine(
            color = Color.Gray,
            start = Offset(0f, 0f),
            end = Offset(size.width, 0f),
            pathEffect = pathEffect
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

Explanation

  • modifier: Modifier for modifying the layout of the screen capture component.

  • screenCaptureController: Controller for managing the screen capture functionality.

  • shareImage: Boolean indicating whether the user intends to share the captured image.

  • onCaptured: Callback invoked when an image is successfully captured or when there's a failure during the capture process. It provides an ImageBitmap representing the captured image and a Throwable in case of any errors.

  • content: A composable function that defines the content to be displayed within the screen capture component. This could include buttons, text, or any other UI elements related to screen capture functionality.

Repository link

Android Demo

Android

iOS Demo
iOS

Connect with us 👇

Top comments (0)