![](/img/trans.png)
[英]Access the login state from every screen (Jetpack Compose + MVVM + Hilt)
[英]Setting up the logic for a Login Screen in Jetpack Compose
因此,对于这个项目,我正在设置一个登录屏幕,用于登录一个数据库,该数据库应该验证 email。这是我第一次真正做这样的事情。 我用 firebase 创建了一个登录页面。但是这次我想登录到 Azure 数据库。 这里有一些代码可以更好地说明
这是 API
@Singleton
interface MMRApi {
@FormUrlEncoded
@POST(LOGIN_EP)
suspend fun sendLoginInfo(
@Field("EmailId") emailId: String,
@Field("MobileMakeModel") mobileMake: String
): Response<LoginCreds>
}
这是请求和响应字段
//Request Data Class
data class LoginCreds(
@SerializedName("EmailId") val emailId: String,
@SerializedName("MobileMakeModel") var mobileModel: String
){
companion object{
const val PLATFORM = "Android"
}
private fun getModel(): String{
return "$PLATFORM ${Build.MODEL}".also { mobileModel = it }
}
}
//Response Data Class
data class LoginResponse(
@SerializedName("data") val data: List<DataInfo>,
@SerializedName("status") val status: Int,
@SerializedName("message") val message: String
){
override fun toString(): String {
return "\n" +
"List of Data: $data" +
"Status: $status" +
"Message:$message"
}
}
data class DataInfo(
@SerializedName("Id") val id: Int,
@SerializedName("CustomerId") val customerId: String,
@SerializedName("UserAttributeId") val userAttributeId: Int,
@SerializedName("Enabled") val enabled: Boolean
){
override fun toString(): String {
return "\n" +
"Id: $id" +
"CustomerId: $customerId" +
"UserAttributeId: $userAttributeId" +
"Enabled: $enabled"
}
}
资料库
class MMRRepository @Inject constructor(private val api: MMRApi) {
suspend fun postLogin(emailId: String, mobileMake: String): Response<LoginCreds>{
return api.sendLoginInfo(emailId, mobileMake)
}
}
视图模型
@HiltViewModel
class LoginViewModel @Inject constructor(private val repository: MMRRepository)
: ViewModel() {
val loginPostResponse: MutableLiveData<Response<LoginCreds>> = MutableLiveData()
fun pushLogin(emailId: String, mobileMake: String){
viewModelScope.launch(Dispatchers.IO) {
val response = repository.postLogin(emailId, mobileMake)
loginPostResponse.postValue(response)
}
}
}
可组合的
@Composable
fun MMRLoginScreen(navController: NavController, loginViewModel: LoginViewModel = hiltViewModel()){
var emailId by rememberSaveable { mutableStateOf("") }
Surface(modifier = Modifier
.fillMaxSize()
.padding(top = 65.dp)
) {
Column(
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
painter = painterResource(id = R.drawable.parabit_logo_orange_blue),
contentDescription = stringResource(R.string.company_logo_string),
contentScale = ContentScale.Fit,
modifier = Modifier
.width(225.dp)
.height(95.dp)
.padding(top = 43.dp)
)
Text(
text = "MMR Bluetooth Access Control",
color = Color(0xFFF47B20),
fontWeight = Bold,
fontSize = 18.sp,
)
Spacer(modifier = Modifier.height(10.dp))
LoginField(loading = false){
loginViewModel.pushLogin(emailId = it, mobileMake = Build.MODEL)
navController.navigate(MMRScreens.MainScreen.name)
}
}
}
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun LoginField(
loading: Boolean = false,
onDone: (String) -> Unit = {email ->}
){
val email = rememberSaveable { mutableStateOf("") }
val keyboardController = LocalSoftwareKeyboardController.current
val valid = remember(email.value){
email.value.trim().isNotEmpty()
}
Column(
modifier = Modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
EmailInput(
emailState = email,
)
SubmitButton(
textId = "Login",
loading = loading,
validInputs = valid
){
onDone(email.value.trim())
keyboardController?.hide()
}
}
}
@Composable
fun SubmitButton(
textId: String,
loading: Boolean,
validInputs: Boolean,
onClick: () -> Unit
) {
Button(
onClick = onClick,
modifier = Modifier
.padding(3.dp)
.fillMaxWidth(),
enabled = !loading && validInputs,
colors = ButtonDefaults.buttonColors(Color(0xFFF47B20))
) {
if (loading) CircularProgressIndicator(modifier = Modifier.size(25.dp))
else Text(text = textId, modifier = Modifier.padding(5.dp))
}
}
任何帮助表示赞赏。 谢谢你。
所以这是一个简单的。 首先,我必须设置 API 来发送我需要的两个字段以获得响应。
@Singleton
interface MMRApi {
@FormUrlEncoded
@POST(LOGIN_EP)
suspend fun sendLoginInfo(
@Field("EmailId") emailId: String,
@Field("MobileMakeModel") mobileMake: String
): LoginResponse
}
一旦输入字段通过, LoginResponse
数据 class 用于存储 API 的响应。 然后对于实例,您将其设置在实例用于告诉您 email 是否有效的位置。
@Module
@InstallIn(SingletonComponent::class)
class AppModule {
@Provides
@Singleton
fun provideLoginApi(): MMRApi{
return Retrofit.Builder()
.baseUrl(BASE_URL)
//Used to pick up the responses for the API Calls
.client(
OkHttpClient.Builder().also { client ->
if (BuildConfig.DEBUG) {
val logging = HttpLoggingInterceptor()
logging.setLevel(HttpLoggingInterceptor.Level.BODY)
client.addInterceptor(logging)
}
}.connectTimeout(100, TimeUnit.SECONDS)
.readTimeout(100, TimeUnit.SECONDS)
.build()
)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(MMRApi::class.java)
}
}
其他一切都是标准的,我能够让登录身份验证工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.