批里批里 (゜-゜)つ🍺 干杯|

七つ一旋桜

园龄:4年2个月粉丝:6关注:3

2022-05-29 21:59阅读: 321评论: 0推荐: 0

toast in jetpack compose

mui3

  1. scaffold

    import androidx.compose.foundation.layout.fillMaxSize
    import androidx.compose.foundation.layout.padding
    import androidx.compose.foundation.layout.wrapContentSize
    import androidx.compose.material3.ExtendedFloatingActionButton
    import androidx.compose.material3.Scaffold
    import androidx.compose.material3.SnackbarHost
    import androidx.compose.material3.SnackbarHostState
    import androidx.compose.material3.Text
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.runtime.remember
    import androidx.compose.runtime.rememberCoroutineScope
    
    val snackbarHostState = remember { SnackbarHostState() }
    val scope = rememberCoroutineScope()
    Scaffold(
        snackbarHost = { SnackbarHost(snackbarHostState) },
        floatingActionButton = {
            var clickCount by remember { mutableStateOf(0) }
            ExtendedFloatingActionButton(
                onClick = {
                    // show snackbar as a suspend function
                    scope.launch {
                        snackbarHostState.showSnackbar(
                            "Snackbar # ${++clickCount}"
                        )
                    }
                }
            ) { Text("Show snackbar") }
        },
        content = { innerPadding ->
            Text(
                text = "Body content",
                modifier = Modifier.padding(innerPadding).fillMaxSize().wrapContentSize()
            )
        }
    )
    

    也可以将显示toast的代码抽离成函数

    fun popupSnackBar(
        scope: CoroutineScope,
        scaffoldState: SnackbarHostState,
        label: String,
        message: String,
        onDismissCallback: () -> Unit = {}
    ) {
        scope.launch {
            scaffoldState.showSnackbar(actionLabel = label, message = message)
            onDismissCallback.invoke()
        }
    }
    
  2. viewmodel

    package com.example.modo_demo.ui.page.login
    
    import androidx.compose.runtime.getValue
    import androidx.compose.runtime.mutableStateOf
    import androidx.compose.runtime.setValue
    import androidx.lifecycle.ViewModel
    import androidx.lifecycle.viewModelScope
    import com.example.modo_demo.data.http.ApiCall
    import dagger.hilt.android.lifecycle.HiltViewModel
    import kotlinx.coroutines.channels.Channel
    import kotlinx.coroutines.flow.receiveAsFlow
    import kotlinx.coroutines.launch
    import javax.inject.Inject
    
    class LoginViewModel: ViewModel() {
        var viewStates by mutableStateOf(LoginViewState()) 
        	private set
        private val _viewEvents = Channel<LoginViewEvent>(Channel.BUFFERED)
        val viewEvents = _viewEvents.receiveAsFlow()
        var errorMessage by mutableStateOf("")
        fun login() {
            viewModelScope.launch {
                try {
                    ApiCall.retrofit.login(username = viewStates.username, password = viewStates.password)
                } catch (e: Exception) {
                    errorMessage = e.message.toString()
                    _viewEvents.send(LoginViewEvent.ErrorMessage(errorMessage))
                    e.printStackTrace()
                }
            }
        }
    }
    
    data class LoginViewState(
        val username: String = "",
        val password: String = "",
    )
    
    /**
     * 一次性事件
     */
    sealed class LoginViewEvent {
        object PopBack : LoginViewEvent()
        data class ErrorMessage(val message: String) : LoginViewEvent()
    }
    
  3. view

    @OptIn(ExperimentalComposeUiApi::class, InternalCoroutinesApi::class)
    @Composable
    fun LoginPage(
        navCtrl: NavController<Screen>,
        scaffoldState: SnackbarHostState,
        viewModel: LoginViewModel = viewModel()
    ) {
        val viewStates = viewModel.viewStates
        val coroutineState = rememberCoroutineScope()
    
        LaunchedEffect(Unit) {
            viewModel.viewEvents.collect {
                if (it is LoginViewEvent.PopBack) {
                    navCtrl.pop()
                } else if (it is LoginViewEvent.ErrorMessage) {
                    popupSnackBar(coroutineState, scaffoldState, label = SNACK_ERROR, it.message)
                }
            }
        }
        
        Button(
            onClick = {
                keyboardController?.hide()
                viewModel.login()
            },
            modifier = Modifier.padding(horizontal = 20.dp)
        ) {
    
            Text(text = "登录")
        }
    }
    

    LaunchedEffect中通过event的collect方法来match显示toast的函数

本文作者:七つ一旋桜

本文链接:https://www.cnblogs.com/poifa/p/16325036.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   七つ一旋桜  阅读(321)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起