How do I achieve this overlapping effect in Jetpack compose. I am trying to get the precise position and placement just like the one shown in the picture, specifically of the ones circled in blue, the close X button and the way the picture preview is placed ontop of the textfield. Using Box with Alignment.CenterStart for the image ontop of the textfield and Alignment.TopStart for the Image with x button at the topleft does not achieve the desired effect. Any help whatsoever would be appreciated
Picture below :
Okay so below is the attached code, and what I have been trying plus the issue that I am currently facing.
@Composable
fun MessageTextField(
value: String,
placeholder: Clause,
imageUri: List<Uri>?,
onCaptureImageClick: () -> Unit,
onPickImageClick: () -> Unit,
onSendButtonClick: () -> Unit,
onRemoveImageClick: (Uri) -> Unit,
onValueChange: (value: String) -> Unit
) {
val containerShape = RoundedCornerShape(
topStart = 20.dp,
topEnd = 20.dp
)
Box {
Column(
modifier = Modifier
.clip(containerShape)
.border(
width = 0.2.dp,
color = Theme.colors.border.primaryOnLight,
shape = containerShape
)
.background(color =
Theme.colors.surfaceInteractive.enabledOnLight)
.padding(
top = Theme.spacing.x3
)
) {
TextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(capitalization =
KeyboardCapitalization.Sentences),
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
unfocusedLabelColor = Color.Transparent
),
textStyle = Theme.typography.textField.copy(
fontWeight = FontWeight.Medium,
fontSize = TEXT_FONT_SIZE.sp,
),
placeholder = {
Text(clause = placeholder)
},
trailingIcon = {
IconButton(
onClick = onSendButtonClick,
enabled = if (value.isNotBlank()) true else
false,
content = {
// SendButton()
}
)
},
maxLines = 6
)
Column(modifier = Modifier.height(25.dp)) {
AnimatedVisibility(
visible = value.isNotBlank(),
enter = scaleIn(),
exit = scaleOut()
) {
Row(modifier = Modifier.padding(start =
Theme.spacing.x4)) {
Image(
image =
Image.Drawable(R.drawable.ic_camera),
modifier = Modifier
.size(22.dp)
.clickable {
onCaptureImageClick.invoke()
}
)
Spacer(modifier =
Modifier.width(Theme.spacing.x3))
Image(
image = Image.Drawable(R.drawable.ic_upload),
modifier = Modifier
.size(22.dp)
.clickable {
onPickImageClick.invoke()
}
)
}
}
}
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.navigationBars))
}
Row(
modifier = Modifier
.fillMaxWidth()
.horizontalScroll(rememberScrollState())
.align(Alignment.BottomStart)
.zIndex(2f)
.graphicsLayer {
translationX = 100f
translationY = -200f
}
) {
imageUri?.forEach {
DismissibleImage(
uri = it,
onRemove = { }
)
}
}
}
}
@Composable
private fun DismissibleImage(uri: Uri, onRemove: () -> Unit) {
Box(
modifier = Modifier.wrapContentSize()
) {
Box(
modifier = Modifier
.clip(RoundedCornerShape(10.dp))
.background(color = Theme.colors.surface.primaryDark)
.size(DISMISSABLE_IMAGE_SIZE.dp)
)
Icon(
image = Icons.Navigation.close,
modifier = Modifier
.size(Theme.spacing.x8)
.zIndex(1f)
.graphicsLayer {
translationX = -25f
translationY = -25f
},
onClick = onRemove
)
}
}
Then this is the result of the code. This is the current issue hat I am facing, something is sort of covering the first half of the Box/Image after using a translationY of 200f
7
I would implement it to have the images on the same layer as the chat and the textfield to have something like a Stack.
Example:
Box(modifier = Modifier.fillMaxSize()) {
LazyColumn {
items(100) {
Divider()
Text("Item $it")
Divider()
}
item {
Box(modifier = Modifier
.height(80.dp)
.fillMaxWidth())
}
}
Box(modifier = Modifier
.height(80.dp)
.fillMaxWidth()
.background(Color.Red)
.align(Alignment.BottomCenter))
Box(
modifier = Modifier
.padding(start = 40.dp, bottom = 50.dp) //crucial for overlapping look
.size(100.dp)
.background(Color.Blue)
.align(Alignment.BottomStart)
)
}
The red Box represents the Textfield and the blue Box the media you want to add. To achieve the overlapping look I decided to align the blue box to the bottom start and add padding on the start and bottom
3