标签: compose-recomposition

5
推荐指数
1
解决办法
1588
查看次数

Jetpack Compose 中的反向写入如何工作?

我们有官方文档展示了 Compose 中向后写入的示例:

@Composable
fun BadComposable() {
   var count by remember { mutableStateOf(0) }

   // Causes recomposition on click
    Button(onClick = { count++ }, Modifier.wrapContentSize()) {
        Text("Recompose")
   }
   Text("$count")
   count++ // Backwards write, writing to state after it has been read
}
Run Code Online (Sandbox Code Playgroud)

我很清楚,更新State可组合对象内的对象会导致向后写入。这种向后写入的规定效果是我们最终会得到无限的重组循环。

然而,有趣的是,count++可组合项底部的增量操作不会触发无限循环的重组。基本上,在 的第一个组合中,一切看起来都很好,因为即使我们在 的主体末尾BadComposable进行了更新,也没有额外的重新组合。countBadComposable

但是,如果您随后按下Button,则回调count++内的增量操作onClick将触发无限的重组循环。

为什么我们必须按下 来Button触发无限循环的重组? 我期望读取一个值并在可组合项的主体中更新它以获得这样的效果就足够了。

Jorge Castillo(感谢您的帮助)暗示这可能是因为状态对象的第一次更新发生在注册 count初始重组范围之前。这个想法的来源BadComposable

android android-jetpack android-jetpack-compose compose-recomposition

5
推荐指数
0
解决办法
523
查看次数

Jetpack Compose 中的持续重组

我正在尝试使用 Jetpack Compose 在我的 Android 应用程序中创建天空视图。我想将它显示在Card带有固定的height. 在晚上,卡片背景变成深蓝色,我希望天空中散布一些闪烁的星星。

为了创建星星闪烁动画,我使用了一个InfiniteTransition对象和一个应用于多个s 的scale属性。这些s 在 a 内部创建,然后使用循环随机传播。我正在使用的完整代码如下所示:animateFloatIconIconBoxWithConstraintsfor

@Composable
fun NightSkyCard() {
    Card(
        modifier = Modifier
            .height(200.dp)
            .fillMaxWidth(),
        elevation = 2.dp,
        shape = RoundedCornerShape(20.dp),
        backgroundColor = DarkBlue
    ) {
        val infiniteTransition = rememberInfiniteTransition()
        val scale by infiniteTransition.animateFloat(
            initialValue = 1f,
            targetValue = 0f,
            animationSpec = infiniteRepeatable(
                animation = tween(1000),
                repeatMode = RepeatMode.Reverse
            )
        )
        
        BoxWithConstraints(
            modifier = Modifier.fillMaxSize()
        ) {
            for (n in …
Run Code Online (Sandbox Code Playgroud)

kotlin android-jetpack-compose jetpack-compose-animation compose-recomposition

5
推荐指数
1
解决办法
2441
查看次数

观察软键盘的可见性,打开/关闭 Jetpack Compose

我正在尝试积极观察软键盘的可见性,目前,我正在尝试使用

WindowInsets.isImeVisible
Run Code Online (Sandbox Code Playgroud)

但我似乎无法观察到它的状态变化。有人提到使用

ViewCompat.setOnApplyWindowInsetsListener()
Run Code Online (Sandbox Code Playgroud)

但我不太明白如何实现这个来观察键盘的可见性。

我已经设法使用

WindowInsets.isImeVisible
Run Code Online (Sandbox Code Playgroud)

但是,它仅适用于我导航到该页面并且键盘自动打开时。

android android-softkeyboard kotlin android-jetpack-compose compose-recomposition

5
推荐指数
1
解决办法
1350
查看次数

AndroidcollectAsStateWithLifecycle() 未在可组合项内收集

我正在使用 composeLazyColumn和 viewModel 通过在我的 viewModel 中更新列表项:

    data class ContactsListUiState(
       val contacts: MutableList<Contact>
    )
    @HiltViewModel
    class ContactsViewModel @Inject constructor(savedStateHandle: SavedStateHandle) : ViewModel() {
    private val _contactsListUiState = MutableStateFlow(ContactsListUiState(mutableListOf()))
    val contactsListUiState: StateFlow<ContactsListUiState> = _contactsListUiState.asStateFlow()

    private fun updateContactsList(newContacts: MutableList<Contact>) {
        _contactsListUiState.update{ currentState ->
            currentState.copy(
                contacts = newContacts
            )
        }
    }
Run Code Online (Sandbox Code Playgroud)

这样我的updateContactsList()函数就会更新 stateFlow,并且我应该在collectAsStateWithLifecycle()可组合函数内部收集联系人列表MainActivity

@OptIn(ExperimentalLifecycleComposeApi::class, ExperimentalFoundationApi::class)
    @Composable
    fun ContactsListScreen(
        navController: NavController,
        modifier: Modifier = Modifier
    ) {
        Log.d("ViewModel", "ContactsListScreen recomposed")
        val uiState by contactsViewModel.contactsListUiState.collectAsStateWithLifecycle()
        Box(modifier = modifier) { …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack-compose kotlin-stateflow compose-recomposition

5
推荐指数
1
解决办法
1977
查看次数

单击按钮时可组合项不会重新组合

我有以下可组合函数。它是一个简单的登录屏幕,包含用户名、密码和提交按钮。

如果用户单击提交按钮时用户名或密码字段为空,则会显示小吃栏。但是,它在第​​一次点击时有效,但后续点击无效。

我认为单击按钮将强制可组合项重新组合,并且如果需要显示小吃栏,则 LaunchEffect 键将为 true。

@Composable
fun Login() {
    var username by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }
    val scaffoldState = rememberScaffoldState()
    var shouldShowSnackBar by remember { mutableStateOf(false) }

    println("LoginScreen")

    LaunchedEffect(key1 = shouldShowSnackBar, block = {
        println("ShouldShowSnackBar")
        scaffoldState.snackbarHostState.showSnackbar(
            message = "Please enter a username and password",
            duration = SnackbarDuration.Short
        )
    })

   Scaffold(
        scaffoldState = scaffoldState
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            OutlinedTextField(
                label = {
                    Text(text = "Username")
                },
                value = username,
                onValueChange = …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack-compose compose-recomposition

5
推荐指数
1
解决办法
547
查看次数

Jetpack Compose Navigation 无限加载屏幕

我正在尝试Navigation使用单个活动和多个Composable屏幕来实现。

这是我的NavHost

@Composable
@ExperimentalFoundationApi
fun MyNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: String = HOME.route,
    viewModelProvider: ViewModelProvider,
    speech: SpeechHelper
) = NavHost(
    modifier = modifier,
    navController = navController,
    startDestination = startDestination
) {
    composable(route = HOME.route) {
        with(viewModelProvider[HomeViewModel::class.java]) {
            HomeScreen(
                speech = speech,
                viewModel = this,
                modifier = Modifier.onKeyEvent { handleKeyEvent(it, this) }
            ) {
                navController.navigateTo(it)
            }
        }
    }

    composable(route = Destination.VOLUME_SETTINGS.route) {
        VolumeSettingsScreen(
            viewModelProvider[VolumeSettingsViewModel::class.java]
        ) { navController.navigateUp() }
    }
} …
Run Code Online (Sandbox Code Playgroud)

android infinite-loop android-jetpack-compose jetpack-compose-navigation compose-recomposition

4
推荐指数
1
解决办法
1879
查看次数

viewModel 的可变值状态不起作用

mutablestate我有一个ViewModel正在尝试在可组合项中设置和访问的内容。当我使用委托属性时,remember它正在工作,但是在 viewModel 中创建它并在 compose 中访问它之后,变量的状态为空如何在 viewModel 中使用状态

当状态位于组合内部时,一切工作正常

var mSelectedText by remember { mutableStateOf("") }
Run Code Online (Sandbox Code Playgroud)

但是当我从 viewModel 更改中使用它并设置我的 OutlinedTextField value = mainCatTitle 和 onValueChange = {mainCatTitle = it} 时,所选标题不会显示在 OutlinedTextField 中为空

 private val _mainCatTitle = mutableStateOf("")
 val mainCatTitle: State<String> = _mainCatTitle
Run Code Online (Sandbox Code Playgroud)

我的可组合项

   var mSelectedText by remember { mutableStateOf("") }
   var mainCatTitle = viewModel.mainCatTitle.value

   Column(Modifier.padding(20.dp)) {

    OutlinedTextField(
        value = mainCatTitle,
        onValueChange = { mainCatTitle = it },
        modifier = Modifier
            .fillMaxWidth()
            .onGloballyPositioned { coordinates ->
                mTextFieldSize …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack-compose compose-recomposition

4
推荐指数
1
解决办法
1007
查看次数

Jetpack Compose - 避免不必要的重组

我正在为我的应用程序创建一个自定义滑块控件,但如果不添加一些丑陋的黑客,我无法避免不必要的重组......

CustomSlider1是一个当值改变时重组其所有子组件的组件;CustomSlider2是我想出的,但代码似乎不正确,所以有人可以告诉我我做错了什么CustomSlider1以及是否CustomSlider2确实正确?

这两个组件之间的区别基本上是我通过 lambda 读取值,并将组件添加到ScopedSlider可组合项中。

我正在使用recomposeHighlighter来显示重组。

这是一个 gif,显示了当我更改其值时两者的行为: 在此输入图像描述

这是代码:

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

        setContent {
            TestTheme {
                Column {
                    var value by remember {
                        mutableStateOf(50f)
                    }

                    CustomSlider1("Custom Slider", value, 50f, true, { value = it }, 0f..100f, 5)
                    Spacer(modifier = Modifier.padding(10.dp))
                    CustomSlider2("Custom Slider 2", { value }, 50f, true, { value = it }, 0f..100f, 5)
                }
            }
        }
    }
} …
Run Code Online (Sandbox Code Playgroud)

android-jetpack-compose compose-recomposition

3
推荐指数
1
解决办法
4053
查看次数

compose中,为什么修改List元素的属性,LazyColumn不刷新

当我修改列表中对象的属性时,UI 不会更新

\n

我的代码\xef\xbc\x9a

\n
    @OptIn(ExperimentalFoundationApi::class)\n    @Composable\n    fun ContactCard(\n    ) {\n        var stateList = remember {\n            mutableStateListOf<ListViewData>()\n        }\n        viewModel!!.recordRespListLiveData!!.observe(this) { it ->\n            it.forEach {\n                stateList.add(ListViewData(false, it))\n            }\n        }\n        LazyColumn() {\n            stateList.forEachIndexed { index, bean ->\n                stickyHeader() {\n                    Box(Modifier.clickable {\n                        stateList[index].visible = true\n                    }) {\n                        ContactNameCard(bean.data.contact, index)\n                    }\n                }\n                items(bean.data.records) { data ->\n                    if (bean.visible) {\n                        RecordItemCard(record = data)\n                    }\n                }\n            }\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

当我单击框时,可见设置为 true,但 RecordItemCard 不显示\xef\xbc\x8c为什么\xef\xbc\x9f

\n

android android-jetpack-compose lazycolumn compose-recomposition

3
推荐指数
1
解决办法
267
查看次数