我的屏幕上有一个使用 Jetpack Compose 实现的设置按钮。我希望当我单击按钮时,我的 ViewModel 应该更改主页的状态以显示设置弹出窗口。但是,按钮正确显示在所需的位置,但可点击的功能似乎根本不起作用。我尝试以不同的方式记录事件,但没有成功。我们如何在 compose 中传递 onclick 监听器?我们不应该吗?
这是按钮的相关代码:
@Composable
fun SettingsButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
val onTestClick: () -> Unit = { // when put on onClick, dosent log when clicked
Log.e("SettingsButton", "onTestClick")
}
Box(
modifier = modifier
.size(54.dp)
.padding(2.dp)
.clickable(
enabled = true,
role = Role.Button,
onClick = onClick // {Log.e(..)} dont work too
),
contentAlignment = Alignment.Center
) {
Image(
bitmap = ImageBitmap.imageResource(id = R.drawable.settings),
contentDescription = "item_icon",
filterQuality = FilterQuality.None,
contentScale = ContentScale.Crop,
modifier = Modifier
.size(40.dp)
)
}
}
也许主页、状态和 viewModel 上下文可以有所帮助:
data class MainState(
val quests: List<Quest> = emptyList(),
val features: List<Feature> = emptyList(),
val isLoading: Boolean = false,
val error: String? = null,
var showOverlay: Feature? = null
)
@Composable
fun MainPage(
state: MainState,
onSettingsClicked: () -> Unit,
//...
) {
Box(modifier = Modifier.fillMaxSize()) {
SettingsButton(
modifier = Modifier.align(Alignment.TopEnd),
onClick = onSettingsClicked
)
//...
}
}
@Composable
fun MainScreen(viewModel: MainViewModel = hiltViewModel()) {
val state by viewModel.mainState.collectAsState()
MainPage(
state,
viewModel::onSettingsClicked,
//...
)
}
@HiltViewModel
class MainViewModel @Inject constructor(
//...
) : ViewModel() {
private val compositeDisposable = CompositeDisposable()
private val _mainState = MutableStateFlow(MainState(isLoading = true))
val mainState: StateFlow<MainState> = _mainState.asStateFlow()
//...
fun onSettingsClicked() {
_mainState.value = _mainState.value.copy(showSettings = true)
}
}
当我做这样的简单测试时,它起作用了:
@Composable
fun MainScreen(viewModel: MainViewModel = hiltViewModel()) {
val state by viewModel.mainState.collectAsState()
MyButton {
Log.e("TEST", "Button was clicked!")
}
}
@Composable
fun MyButton(onClick: () -> Unit) {
Button(onClick = onClick) {
Text(text = "Click me")
}
}
有人可以帮助我理解为什么可点击功能没有按预期工作吗?
不要将
clickable
设置为 Box
,而是将其设置为 Image
,如下所示:
@Composable
fun SettingsButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
val onTestClick: () -> Unit = { //
Log.e("SettingsButton", "onTestClick")
}
Box(
modifier = modifier
.size(54.dp)
.padding(2.dp),
contentAlignment = Alignment.Center
) {
Image(
bitmap = ImageBitmap.imageResource(id = R.drawable.settings),
contentDescription = "item_icon",
filterQuality = FilterQuality.None,
contentScale = ContentScale.Crop,
modifier = Modifier.size(40.dp).clickable(
enabled = true,
role = Role.Button,
onClick = onClick // {Log.e(..)}
)
)
}
}