androidkotlinandroid-jetpack-composeclickable

Jetpack Compose column clickable only in elements area


When the code below runs, it overrides the screen elements below. To prevent the elements below from being accidentally clicked, I added the 'clickable' attribute to the column, which should capture clicks. However, as shown in the image, not the entire column area is clickable and items underneath may be clicked accidentally. Is there any way to make the entire column area clickable? Of course I can lock the elements underneath if the notification is visible, but maybe there is a simple solution such as entire column area clickable?

enter image description here


@Composable
fun ShowAddedUserData(
    userName: String,
    userType: String,
    userPass: String,
    onClear: () -> Unit
) {

    val name = stringResource(id = R.string.user_name) + " : " + userName
    val type = stringResource(id = R.string.user_type) + " : " + userType
    val pass = stringResource(id = R.string.password) + " : " + userPass
    val userInfoToCopy = "$name\n$type\n$pass"
    val clipboardManager = LocalClipboardManager.current
    val localContext = LocalContext.current
    val copyDataInfo = stringResource(id = R.string.data_copied_to_clipboard)

    Spacer(modifier = Modifier.height(20.dp))
    Column(
        modifier = Modifier.clickable {  },
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            modifier = Modifier.padding(horizontal = 20.dp),
            text = stringResource(id = R.string.user_created)
        )
    }

    Spacer(modifier = Modifier.height(20.dp))
    Column(
        modifier = Modifier
            .clip(shape = RoundedCornerShape(20.dp))
            .background(color = Color.LightGray),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        Spacer(modifier = Modifier.height(10.dp))
        Text(modifier = Modifier.padding(horizontal = 20.dp), text = name)
        Text(modifier = Modifier.padding(horizontal = 20.dp), text = type)
        Text(modifier = Modifier.padding(horizontal = 20.dp), text = pass)
        Spacer(modifier = Modifier.height(20.dp))
        Image(
            painter = painterResource(id = R.drawable.ic_copy_content_blue),
            contentDescription = "copy content",
            Modifier.clickable {
                clipboardManager.setText(AnnotatedString(userInfoToCopy))
                Toast.makeText(localContext, copyDataInfo, Toast.LENGTH_SHORT).show()
            })
        Text(
            modifier = Modifier.padding(horizontal = 5.dp),
            text = stringResource(id = R.string.copy_to_memory),
            fontSize = 12.sp
        )
        Spacer(modifier = Modifier.height(30.dp))
        Button(onClick = onClear) {
            Text(text = stringResource(id = R.string.clear))
        }
        Spacer(modifier = Modifier.height(10.dp))
    }
}

Solution

  • Have a look at AlertDialog and Dialog, which provide an easy way to cover your use case.

    AlertDialog(
        icon = {},
        title = {},
        text = {
            // This actually is for Text, but you can pass any Composable here
            ShowAddedUserData(/** ... **/)
        },
        onDismissRequest = {},
        confirmButton = {},
        dismissButton = {}
    )
    

    or

    Dialog(onDismissRequest = { }) {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .padding(16.dp),
            shape = RoundedCornerShape(16.dp),
        ) {
            ShowAddedUserData(/** ... **/)
        }
    }
    

    Alternatively, you can wrap your ShowAddedUserData Composable into a Surface. A Surface by default consumes all interactions in the area it is displayed in.