首页 > 解决方案 > 应用程序返回前台时不显示 PIN 屏幕

问题描述

我正在 Jetpack Compose 中构建一个应用程序,用户可以在其中设置将存储在 sharedPrefs 中的个性化 PIN。每次应用程序回到前台(并且用户已经预先设置了一个 PIN),应用程序应该打开“输入 PIN”屏幕。在应用程序启动时,一切正常,并提示用户输入他们的 PIN,但一旦应用程序进入后台然后返回前台,“输入 PIN”屏幕将不再显示。

主要活动

class MainActivity : ComponentActivity() {

    private val openPinScreen = MutableStateFlow(false)

    @Inject
    lateinit var sharedPrefsRepository: SharedPrefsRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            val pinState = openPinScreen.collectAsState()

            MyAppTheme {
                MyApp(pinState.value)
            }
        }
    }

    override fun onResume() {
        super.onResume()
        sharedPrefsRepository.getPin()?.let {
            openPinScreen.value = sharedPrefsRepository.hasSetPin()
        }
    }
}

fun MyApp(showPin: Boolean) {
    val navController = rememberNavController()

    NavHost(navController = navController, startDestination = Route.Splash.route) {
        composable(Route.Splash.route) {
            SplashScreen {
                navController.apply {
                    popBackStack()
                    navigate(Route.MainContent.route)
                }
            }
        }
        composable(Route.MainContent.route) {
            MainContent(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.White),
                isPinRequired = showPin
            )
        }
    }
}

主要内容.kt

fun MainContent(
    modifier: Modifier,
    isPinRequired: Boolean,
    viewModel: MainViewModel = hiltViewModel()
) {
    val navController = rememberNavController()
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination?.route

    val shouldOpenPinScreen by remember {
        mutableStateOf(isPinRequired)
    }

    LaunchedEffect(isPinRequired){
        if (shouldOpenPinScreen) navController.navigate(Route.Pincode.route)
    }

    Scaffold(...){ 
        NavHost(
            navController = navController,
            startDestination = Route.Home.route
        ) {
            composable(...) {...}
            composable(...) {...}
            composable(...) {...}
    }
}

我在调试过程中检查过 MainActivity 中的一切正常,但是在尝试将值获取到相应的 Composable 时似乎存在问题。具体来说,

LaunchedEffect(isPinRequired){
   if (shouldOpenPinScreen) navController.navigate(Route.Pincode.route)
}

不再调用,导航到Route.Pincode.route也不会触发。替换也没有帮助LaunchedEffect(isPinRequired)LaunchedEffect(Unit)有人对我如何解决这个问题有任何想法吗?

标签: androidkotlinandroid-jetpack-composeandroid-jetpack-navigation

解决方案


问题在于以下几行:

val shouldOpenPinScreen by remember {
    mutableStateOf(isPinRequired)
}

shouldOpenPinScreen修复 的第一个值isPinRequired并且不使用新值更新。您可以isPinRequired作为键传递给remember,在这种情况下,变量将被更新。但我通常看不出拥有这个变量的意义,如果它总是与 相同isPinRequired,你可以删除它并通过使用来替换它isPinRequired


推荐阅读