Почему мой NavHost перекомпоновывает и вызывает цикл навигации в Jetpack Compose? [дубликат]Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Почему мой NavHost перекомпоновывает и вызывает цикл навигации в Jetpack Compose? [дубликат]

Сообщение Anonymous »

У меня возникла проблема с моим приложением Jetpack Compose, из-за которой NavHost постоянно перекомпоновывает и вызывает зацикливание навигации. Ниже приведена упрощенная версия моего кода, демонстрирующая проблему.
Когда состояние меняется на SECOND при нажатии кнопки в главном компоненте
Button(onClick = { temViewModel.updateState() }) { Text("clickme") }

маршрут NavTest осуществляется из MainActivity NavHost. Однако компонуемые журналы NavTest ведут непрерывную запись, и кажется, что NavHost постоянно перекомпоновывает, вызывая цикл навигации.
Из журналов, размещенных внизу, видно, что цикл навигации постоянно перекомпоновывается. .
Кто-нибудь знает, почему и почему они растут последовательно. вы можете видеть, что «NavTest» начинается с 1, затем 2, затем 3... подряд
MainActivty с NavHost
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Construction
import androidx.compose.material.icons.filled.Games
import androidx.compose.material.icons.filled.Home
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.collectAsState
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.compose.ui.graphics.vector.ImageVector
import com.thelot.simplescorecards.ui.screens.home.NavTest
import com.thelot.simplescorecards.ui.screens.home.MyStates
import com.thelot.simplescorecards.ui.screens.home.TemViewModel
import com.thelot.simplescorecards.ui.screens.home.HomeContainer
import com.thelot.simplescorecards.ui.theme.AppTheme
import dagger.hilt.android.AndroidEntryPoint

sealed class Screen(val route: String, val title: String, val icon: ImageVector) {
object Home : Screen("home", "Home", Icons.Default.Home)
object NavTest : Screen("navTest", "NavTest", Icons.Default.Games)
}

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContent {
val navController = rememberNavController()
val tempViewModel: TemViewModel = hiltViewModel()
val tempState = tempViewModel.myState.collectAsState()

AppTheme(darkTheme = true) {
Scaffold(topBar = {},
content = { paddingValues ->
NavHost(modifier = Modifier.padding(paddingValues),
navController = navController, startDestination = Screen.Home.route
) {
composable(Screen.Home.route) {
if (tempState.value == MyStates.SECOND) {
Log.d("INN tempState", ": ${tempState.value}")
navController.navigate(Screen.NavTest.route)
} else {
Log.d("INN tempState ELSE", ": ${tempState.value}")
HomeContainer(tempViewModel)
}
}
composable(Screen.NavTest.route) {
Log.d("INN NavTestRoute", ": NavTest")
NavTest()
}
}
})
}
}
}
}

Моя модель представления
@HiltViewModel
class TemViewModel @Inject constructor() : ViewModel() {
private val _myState = MutableStateFlow(MyStates.FIRST)
val myState = _myState

fun updateState() {
_myState.value = if (_myState.value == MyStates.FIRST) MyStates.SECOND else MyStates.FIRST
}
}

enum class MyStates {
FIRST,
SECOND
}

Компонуемые Home Composable и NavTest
@Composable
fun Home(temViewModel: TemViewModel) {
Button(onClick = { temViewModel.updateState() }) {
Text("click me")
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NavTest() {
Log.d("IN NavTest", "NavTest Composable")
Text("hello NavTest")
}

Журналы
INN tempState D : SECOND
INN NavTestRoute D : NavTest
INN tempState D : SECOND
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN tempState D : SECOND
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN tempState D : SECOND
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN tempState D : SECOND
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest
INN NavTestRoute D : NavTest

С помощью LaunchedEffect я получаю 4 повторяющихся журнала «NavTest». Почему?
composable(Screen.Home.route) {
LaunchedEffect(tempState.value) {
if (tempState.value == MyStates.SECOND) {
Log.d("INN tempState", ": ${tempState.value}")
navController.navigate(Screen.NavTest.route)
}
}

HomeContainer(tempViewModel)
}

Журналы с LaunchedEffect
INN tempState D : SECOND
INN NavTestRoute D NavTest
INN NavTestRoute D NavTest
INN NavTestRoute D NavTest
INN NavTestRoute D NavTest


Подробнее здесь: https://stackoverflow.com/questions/793 ... ck-compose
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»