Jetpack Compose - create background which doesn't resize with keyboard in a Navigation stack

395 Views Asked by At

*I have the below code which I've created on the back of the below link to another Stackoverflow question. The line getWindow().setBackgroundDrawableResource(R.drawable.sign_in_sign_up_background) in particular is the code I've carried over into my onCreate method.

Jetpack Compose - stop background resizing with keyboard

However, with this code, the background appears in both my SignInOrSignUpMasterView and OnboardingStartView.

How can I get is so that the sign_in_sign_up_background is only part of the SignInOrSignUpMasterView and doesn't resize when the keyboard pops up?

Note: I have added comments to the below code to show which .kt file the code sits in. Note: I have also added android:windowSoftInputMode="adjustResize" to my AndroidManifest.xml where android:name=".MainActivity"

//MainActivity.kt file
class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        getWindow().setBackgroundDrawableResource(R.drawable.sign_in_sign_up_background)
        setContent {

            //Used to determine where the starting launch point of the app is
            val user by remember { mutableStateOf(Firebase.auth.currentUser) }
            AppNavigation(
                startDestination = if (user == null) {
                    "signInOrSignUp"
                } else {
                    "onboarding"
                }
            )

        }
    }
}

@Composable
fun AppNavigation(
    navController: NavHostController = rememberNavController(),
    startDestination: String = "signInOrSignUp"
) {
    NavHost(
        navController = navController,
        startDestination = startDestination
    ) {
        composable("signInOrSignUp") {
            Box(modifier = Modifier
                .fillMaxSize()
                .background(Color.White.copy(alpha = 0.5F))) {
                SignInOrSignUpMasterView(navController = navController)
            }

        }
        composable("onboarding") {
            OnboardingStartView(navController = navController)
        }
    }
}


    //SignInOrSignUp.kt file

    class SignInOrSignUp : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SignInOrSignUpMasterView(rememberNavController())
        }

    }

}
@Composable
fun SignInOrSignUpMasterView(navController: NavController) {
    var text by remember { mutableStateOf(TextFieldValue("")) }

    Column {

        Spacer(modifier = Modifier.weight(1f))

        TextField(
            value = text,
            onValueChange = { newText ->
                text = newText
            }
        )

        Button(onClick = {
            navController.navigate("onboarding")
        }) {
            Text("Move to Onboarding")
        }
    }
}


    //OnboardingStartView.kt file

class OnboardingStart : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            OnboardingStartView(rememberNavController())
        }
    }
}
    @Composable
    fun OnboardingStartView(navController: NavController) {
        Text(text = "Onboarding View")
    }*
1

There are 1 best solutions below

2
Halifax On

Since you want to be able to update the background in real time, I modified the code for you and attached the gif image effect....

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.os.Bundle
import android.view.Window
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.text.input.TextFieldValue
import androidx.navigation.NavController
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

            val user by remember { mutableStateOf<String?>(null) }
            AppNavigation(
                startDestination = if (user == null) {
                    "signInOrSignUp"
                } else {
                    "onboarding"
                }
            )

        }
    }
}
@Composable
fun AppNavigation(
    navController: NavHostController = rememberNavController(),
    startDestination: String = "signInOrSignUp"
) {
    NavHost(
        navController = navController,
        startDestination = startDestination
    ) {
        composable("signInOrSignUp") {
            Box(modifier = Modifier
                .fillMaxSize()
                .background(Color.White.copy(alpha = 0.5F))) {
                SignInOrSignUpMasterView(navController = navController)
            }

        }
        composable("onboarding") {
            OnboardingStartView(navController = navController)
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SignInOrSignUpMasterView(navController: NavController) {
    var text by remember { mutableStateOf(TextFieldValue("")) }
    val screenWindow = rememberAndroidUiWindow()
    LaunchedEffect(Unit) {
        screenWindow?.setBackgroundDrawableResource(R.drawable.ic_background)
    }

    Column {

        Spacer(modifier = Modifier.weight(1f))

        TextField(
            value = text,
            onValueChange = { newText ->
                text = newText
            }
        )

        Button(onClick = {
            navController.navigate("onboarding")
        }) {
            Text("Move to Onboarding")
        }
    }
}

@Composable
fun OnboardingStartView(navController: NavController) {
    val screenWindow = rememberAndroidUiWindow()
    LaunchedEffect(Unit) {
        screenWindow?.setBackgroundDrawable(null)
    }
    Text(text = "Onboarding View")
}

@Composable
fun rememberAndroidUiWindow(): Window? {
    val view = LocalView.current
    return remember(view) { view.context.findAndroidUiWindow() }
}

private fun Context.findAndroidUiWindow(): Window? {
    var context = this
    while (context is ContextWrapper) {
        if (context is Activity) return context.window
        context = context.baseContext
    }
    return null
}

enter image description here