Home > Software design >  Compose elements not overlapping
Compose elements not overlapping

Time:11-29

I am trying to overlap two different compose elements. I want to show a toast kind of message at the top whenever there is an error message. I don't want to use a third party lib for such an easy use case. I plan to use the toast in every other composable screen for displaying error message. Below is the layout which i want to achieve

enter image description here

So I want to achieve the toast message saying "Invalid PIN, please try again".

@Composable
fun MyToast(title: String) {
    Card(
        modifier = Modifier
            .absoluteOffset(x = 0.dp, y = 40.dp)
            .background(
                color = MaterialTheme.colors.primaryVariant,
                shape = RoundedCornerShape(10.dp)
            ), elevation = 20.dp
    ) {
        Row(
            modifier = Modifier
                .background(color = MaterialTheme.colors.primaryVariant)
                .padding(12.dp),
            horizontalArrangement = Arrangement.Start,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Image(
                painter = painterResource(id = R.drawable.error_circle),
                contentDescription = title
            )
            Text(
                text = title,
                fontFamily = FontFamily(Font(R.font.inter_medium)),
                fontSize = 12.sp,
                color = MaterialTheme.colors.primary,
                modifier = Modifier.padding(horizontal = 10.dp)
            )
        }
    }

}

and my screen composable is as follows

@Composable
fun Registration(navController: NavController, registrationViewModel: RegistrationViewModel) {
Scaffold() {
       Box(){
           MyToast(
                        title = "Invalid pin, please try again"
                    )
          Column() {
              //my other screen components
          }  
        }
}

I will add the AnimatedVisibility modifier later to MyToast composable. First I need to overlap MyToast over all the other elements and somehow MyToast is just not visible

CodePudding user response:

If you want the child of a Box to overlay/overlap its siblings behind, you should put it at the last part in the code

Box(
    modifier = Modifier.fillMaxSize(),
    contentAlignment = Alignment.Center
) {

    Box(
        modifier = Modifier.background(Color.Red).size(150.dp)
    )

    // your Toast
    Box(
        modifier = Modifier.background(Color.Green).size(80.dp)
    )
}

enter image description here

So if I put the green box before the bigger red box like this

Box(
    modifier = Modifier.fillMaxSize(),
    contentAlignment = Alignment.Center
) {

    // your Toast
    Box(
        modifier = Modifier.background(Color.Green).size(80.dp)
    )

    Box(
        modifier = Modifier.background(Color.Red).size(150.dp)
    )
}

the green box will hide behind the red one

enter image description here

CodePudding user response:

You have to solutions, you can either put the Toast in the bottom of your code because order matters in compose:

@Composable
fun Registration(navController: NavController, registrationViewModel: RegistrationViewModel) {
    Scaffold() {
        Box() {
            Column() {
                //my other screen components
            }
            MyToast(
                title = "Invalid pin, please try again"
            )
        }
    }
} 

Or you can keep it as it is, but add zIndex to the Toast:

@Composable
fun MyToast(title: String) {
    Card(
        modifier = Modifier
            .absoluteOffset(x = 0.dp, y = 40.dp)
            .zIndex(10f) // add z index here
            .background(
                color = MaterialTheme.colors.primaryVariant,
                shape = RoundedCornerShape(10.dp)
            ), elevation = 20.dp
    ) {
        Row(
            modifier = Modifier
                .background(color = MaterialTheme.colors.primaryVariant)
                .padding(12.dp),
            horizontalArrangement = Arrangement.Start,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Image(
                painter = painterResource(id = R.drawable.error_circle),
                contentDescription = title
            )
            Text(
                text = title,
                fontFamily = FontFamily(Font(R.font.inter_medium)),
                fontSize = 12.sp,
                color = MaterialTheme.colors.primary,
                modifier = Modifier.padding(horizontal = 10.dp)
            )
        }
    }

}

Note: elevation in Card composable is not the same as elevation in XML so it's not going to make the composable in the top, it will just add a shadow but if you want to give the composable a higher z order use Modifier.zIndex(10f)

  • Related