build.gralde(:app)
dependencies {
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
//Activity KTX for viewModels()
implementation("androidx.activity:activity-ktx:1.3.1")
//Architectural Components
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1")
//Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3")
//Coroutine Lifecycle Scopes
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.3.1")
kapt "com.android.databinding:compiler:3.1.4"
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val viewModel by viewModels<MainViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater).also { binding->
setContentView(binding.root)
}
lifecycleScope.launchWhenStarted {
viewModel.loginUiState.collect {
when(it) {
is MainViewModel.LoginUiState.Success -> {
Snackbar.make(
binding.root,
"登录成功",
Snackbar.LENGTH_LONG
).show()
binding.progressBar.isVisible = false
}
is MainViewModel.LoginUiState.Error -> {
Snackbar.make(
binding.root,
it.message,
Snackbar.LENGTH_LONG
).show()
binding.progressBar.isVisible = false
}
is MainViewModel.LoginUiState.Loading -> {
binding.progressBar.isVisible = true
}
else -> Unit
}
}
}
binding.btnLogin.setOnClickListener {
viewModel.login(
binding.username.text.toString(),
binding.password.text.toString())
}
}
}
MainViewModel.kt
class MainViewModel : ViewModel() {
private val _loginUiState = MutableStateFlow<LoginUiState>(LoginUiState.Empty)
val loginUiState: StateFlow<LoginUiState> = _loginUiState
fun login(username: String, password: String) = viewModelScope.launch {
_loginUiState.value = LoginUiState.Loading
delay(2000L)
if (username == "android" && password == "123456") {
_loginUiState.value = LoginUiState.Success
} else {
_loginUiState.value = LoginUiState.Error("密码错误")
}
}
sealed class LoginUiState {
object Success : LoginUiState()
data class Error(val message: String) : LoginUiState()
object Loading : LoginUiState()
object Empty : LoginUiState()
}
}