gpt4 book ai didi

android - Jetpack Compose 显示来自 viewmodel 的小吃吧 - 单场直播 Activity

转载 作者:行者123 更新时间:2023-12-04 11:33:23 29 4
gpt4 key购买 nike

我正在构建一个 jetpack compose 应用程序,我希望我的 View 模型告诉我的 compose 函数通过向它发送一个事件来显示一个 snackbar 。我已经阅读了多篇关于 Kotlin 单现场事件案例的博客文章,并尝试使用 Compose 和 Kotlin Flow 来实现它。我设法从 View 模型发送事件(我在日志中看到它),但我不知道如何在可组合函数中接收它。有人可以帮我弄清楚吗?这是我的实现。

class HomeViewModel() : ViewModel() {
sealed class Event {
object ShowSheet : Event()
object HideSheet : Event()
data class ShowSnackBar(val text: String) : Event()
}

private val eventChannel = Channel<Event>(Channel.BUFFERED)
val eventsFlow: Flow<Event> = eventChannel.receiveAsFlow()

fun showSnackbar() {
Timber.d("Show snackbar button pressed")
viewModelScope.launch {
eventChannel.send(Event.ShowSnackBar("SnackBar"))
}
}
}
@Composable
fun HomeScreen(
viewModel: HomeViewModel,
) {
val context = LocalContext.current

val scaffoldState = rememberScaffoldState()
val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)

val lifecycleOwner = LocalLifecycleOwner.current
val eventsFlowLifecycleAware = remember(viewModel.eventsFlow, lifecycleOwner) {
eventsFlow.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)
}

LaunchedEffect(sheetState, scaffoldState.snackbarHostState) {
eventsFlowLifecycleAware.onEach {
when (it) {
HomeViewModel.Event.ShowSheet -> {
Timber.d("Show sheet event received")
sheetState.show()
}
HomeViewModel.Event.HideSheet -> {
Timber.d("Hide sheet event received")
sheetState.hide()
}
is HomeViewModel.Event.ShowSnackBar -> {
Timber.d("Show snack bar received")
scaffoldState.snackbarHostState.showSnackbar(
context.getString(it.resId)
)
}
}
}
}

ModalBottomSheetLayout(
sheetState = sheetState,
sheetContent = {
Text("Sheet")
}
) {
Button(
onClick = {
viewModel.showSheet()
}
) {
Text("Show SnackBar")
}
}
}
作为引用,我使用了这些博客文章:
  • Android SingleLiveEvent Redux with Kotlin Flow
  • A safer way to collect flows from Android UIs
  • 最佳答案

    好的,我使用了错误的方法,我不能发送事件,我必须更新 View 状态并检查我是否应该在重组时显示 snackbar 。像这样的东西:
    您将 SnackBar 状态存储在 View 模型中

    class HomeViewModel: ViewModel() {
    var isSnackBarShowing: Boolean by mutableStateOf(false)
    private set

    private fun showSnackBar() {
    isSnackBarShowing = true
    }

    fun dismissSnackBar() {
    isSnackBarShowing = false
    }
    }
    在 View 中,您使用 LaunchedEffect 来检查在重新组合 View 时是否应该显示 snackbar
    @Composable
    fun HomeScreen(
    viewModel: HomeViewModel,
    ) {
    val onDismissSnackBarState by rememberUpdatedState(newValue = onDismissSnackBar)

    if (isSnackBarShowing) {
    val snackBarMessage = "Message"
    LaunchedEffect(isSnackBarShowing) {
    try {
    when (scaffoldState.snackbarHostState.showSnackbar(
    snackBarMessage,
    )) {
    SnackbarResult.Dismissed -> {
    }
    }
    } finally {
    onDismissSnackBarState()
    }
    }
    }

    Row() {
    Text(text = "Hello")
    Spacer(modifier = Modifier.weight(1f))
    Button(
    onClick = {
    viewModel.showSnackBar()
    }
    ) {
    Text(text = "Show SnackBar")
    }
    }
    }

    关于android - Jetpack Compose 显示来自 viewmodel 的小吃吧 - 单场直播 Activity ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67100132/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com