相关疑难解决方法(0)

为什么有时没有记住的 mutableStateOf 也能工作?

我一直在使用 Jetpack Compose Desktop。我注意到一些我真的不明白的事情:

import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

@Composable
@Preview
fun App() {
    var text by mutableStateOf("Hello, World!")

    MaterialTheme {
        TextField(text, onValueChange = { text = it })
        Button(onClick = {
            text = "Hello, Desktop!"
        }) {
            Text(text)
        }
    }
}

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        App()
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么我可以更改 中的文本TextField?我认为在每次重组时,可变状态都会使用初始值重新实例化:所以Text应该无法更改

import androidx.compose.desktop.ui.tooling.preview.Preview
import …
Run Code Online (Sandbox Code Playgroud)

kotlin android-jetpack-compose mutablestateof

11
推荐指数
1
解决办法
3255
查看次数

Jetpack Compose State:修改类属性

下面的两个示例简单地将“a”添加到给定的默认值。该compose_version使用的1.0.0-alpha03是最新的截至今天(据我所知)。

这个例子与我在研究过程中发现的大多数例子最相似。

示例 1

@Composable
fun MyScreen() {
    val (name, setName) = remember { mutableStateOf("Ma") }

    Column {
        Text(text = name) // 'Ma'
        Button(onClick = {
                setName(name + "a") // change it to 'Maa'
        }) {
            Text(text = "Add an 'a'")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,这并不总是实用的。例如,数据比单个字段更复杂。例如一个类,甚至一个Room data class.

示例 2

// the class to be modified
class MyThing(var name: String = "Ma");


@Composable
fun MyScreen() {
    val (myThing, setMyThing) = remember { mutableStateOf(MyThing()) }

    Column …
Run Code Online (Sandbox Code Playgroud)

android state kotlin android-jetpack android-jetpack-compose

8
推荐指数
2
解决办法
1746
查看次数

用作输入参数的 Lambda 函数会导致重组

考虑下面的片段

fun doSomething(){
}

@Composable
fun A() {
    Column() {
        val counter = remember { mutableStateOf(0) }
        B {
            doSomething()
        }
        Button(onClick = { counter.value += 1 }) {
            Text("Click me 2")
        }
        Text(text = "count: ${counter.value}")
    }
}

@Composable
fun B(onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("click me")
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当按下“click me 2”按钮时,B compose 函数将被重新组合,尽管其中的任何内容都没有改变。

澄清: doSomething 用于演示目的。如果您坚持要一个实际的例子,您可以考虑以下 B 的用法:

B{
    coroutinScope.launch{
        bottomSheetState.collapse()
        doSomething()
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 为什么这个 lamda 函数会导致重组
  2. 修复它的最佳方法

我对这个问题的理解

从 compose 编译器报告中我可以看到 B …

android android-jetpack-compose compose-recomposition

7
推荐指数
1
解决办法
2818
查看次数

Android Jetpack Compose - 每次文本字段值更改时都会重新组合可组合函数

我用来TextField获取用户输入并使用 stateflow 来处理视图模型中的文本状态/值。

问题是每次TextField的值发生变化时,HomeContent()函数都会被重新组合。
布局检查器输出图像 我的问题是,仅仅HomeContent()因为值发生变化就可以重构整个函数TextField,还是有办法避免函数重构?

视图模型

class MyViewModel() : ViewModel() {
    private val _nameFlow = MutableStateFlow("")
    val nameFlow = _nameFlow.asStateFlow()

    fun updateName(name: String) {
        _nameFlow.value = name
    }
}
Run Code Online (Sandbox Code Playgroud)

主要活动

class MainActivity : ComponentActivity() {
    private val myViewModel by viewModels<MyViewModel>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AppArchitectureTheme {
                HelloScreen(myViewModel)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

主屏幕

@Composable
fun HelloScreen(viewModel: MyViewModel) {
    val name = viewModel.nameFlow.collectAsState()
    HelloContent(
        provideName = { …
Run Code Online (Sandbox Code Playgroud)

android android-jetpack-compose android-compose-textfield

6
推荐指数
1
解决办法
3795
查看次数

当 Jetpack Compose 中的指定流程发生更改时,如何启动重组?

我知道Column(){...}b1orb2改变时,将会重新组合。

如果我希望只有改变的Column(){...}时候才可以重新组合,而改变的 时候不重新组合,怎么办?b2Column(){...}b1

@Composable
fun ScreenDetail(
    mViewMode: SoundViewModel
) {
      val b1=mViewMode.a1.collectAsState(initial = 0)
      val b2=mViewMode.a2.collectAsState(initial = 0)
      
      Column() {
          Text(" ${b1.value}   ${b2.value}")

          Text(Calendar.getInstance().time.toSeconds())
      }
}

fun Date.toSeconds():String{
    return SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US).format(this)
}

class SoundViewModel(): ViewModel() {
    var i = 0
    val a1: Flow<Int> = flow {
        while (true) {
            emit(i++)
            delay(1000)
        }
    }

    val a2: Flow<Int> = flow {
        while (true) {
            emit(i)
            delay(2000)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

kotlin android-jetpack-compose compose-recomposition

2
推荐指数
1
解决办法
1148
查看次数

Android compose Icon重组问题

我创建了一个仅显示一个图标、两个文本和两个按钮的应用程序。单击任何按钮时,相应的文本都会更新,因为它取决于我的函数中传递的值。但与文本一起,每次图标重新组合时,它甚至不依赖于任何值。

data class TestUIState(
    val counterA: Int = 0,
    val counterB: Int = 0,
)

@HiltViewModel
class TestViewModel @Inject constructor() : ViewModel() {
    val uiFlow = MutableStateFlow(TestUIState())
    val data: TestUIState
        get() = uiFlow.value


    fun increaseCounterA() {
        uiFlow.value = data.copy(counterA = data.counterA + 1)
    }

    fun increaseCounterB() {
        uiFlow.value = data.copy(counterB = data.counterB + 1)
    }
}

@Composable
fun TestCompose(
    uiValueState: State<TestUIState>,
    increaseCounterA: () -> Unit,
    increaseCounterB: () -> Unit,
) {
    Column(modifier = Modifier.fillMaxSize()) {
        Icon(
            painter = painterResource(id = …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack-compose

2
推荐指数
1
解决办法
497
查看次数