如何构建Android MVVM应用程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何构建Android MVVM应用程序相关的知识,希望对你有一定的参考价值。
参考技术A 可以使用框架,参考内容如下:1、概述
Databinding
是一种框架,MVVM是一种模式,两者的概念是不一样的。咱的理解DataBinding是一个实现数据和UI绑定的框架,只是一个实现MVVM模式的工具。ViewModel和View可以通过DataBinding来实现单向绑定和双向绑定,这套UI和数据之间的动态监听和动态更新的框架Google已经帮咱们做好了。在MVVM模式中ViewModel和View是用绑定关系来实现的,所以有了DataBinding
使咱们构建android
MVVM
应用程序成为可能。
之前看了很多关于DataBinding的博客和相关的一些Demo,大多数就是往xml布局文件传入一些数据,然后把这些数据绑定到控件上(
如TextView
binding:text=“@user.name
),接着在这些控件上(如Button
binding:setOnClickListener=”@user.listener”)
设置一些事件到控件上,基本讲述都是DataBinding的基本用法。但是并没有人告诉把一个onClickListener
写到一个类并把这个listener绑定到xml里面上是不是不太好,也没有人告诉这个和xml布局绑定的ViewModel类应该放哪些数据,应该做什么事?应该如何设计?更是很少有博文来告诉在Android
中如何通过Data
Binding
去构建MVVM
的应用框架。这也就是是本篇文章的重点。接下来,咱们先来看看什么是MVVM,然后在一步一步来设计整个应用程序框架。
如何使用 MVVM 架构实现 Firebase Google SignIn?
【中文标题】如何使用 MVVM 架构实现 Firebase Google SignIn?【英文标题】:How to implement Firebase Google SignIn with MVVM architecture? 【发布时间】:2019-10-20 18:46:13 【问题描述】:我正在构建一个应用程序,但我目前面临一个问题:我按照google guide 在 LoginActivity 中编写了我的 Google/Facebook 登录按钮的所有事件。但是,我不想将业务代码保留在活动中以遵循 MVVM 架构。因此,如何放置 Firebase 方法(需要活动引用和生命周期回调)?
我尝试了一个正在运行的 LoginViewModel,但它引用了 LoginActivity
class LoginViewModel(application: Application) : BaseViewModelContext(application)
lateinit var auth: FirebaseAuth
val Tag: String = LoginViewModel::class.java.simpleName;
val gso: GoogleSignInOptions
val googleSignInClient: GoogleSignInClient
init
auth = FirebaseAuth.getInstance()
gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(application.getString(R.string.default_client_id))
.build()
googleSignInClient = GoogleSignIn.getClient(application, gso)
fun activityForResultLogin(requestCode:Int, resultCode: Int, data: Intent?, activity: Activity)
if(requestCode == Constants.RC_SIGN_IN)
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try
// Google Sign In was successful, authenticate with Firebase
val account = task.getResult(ApiException::class.java)
firebaseAuthWithGoogle(account!!, activity)
catch (e: ApiException)
// Google Sign In failed, update UI appropriately
Log.w(Tag, "Google sign in failed", e)
// ...
private fun firebaseAuthWithGoogle(acct: GoogleSignInAccount, activity: Activity)
Log.d(Tag, "firebaseAuthWithGoogle:" + acct.id!!)
val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
auth.signInWithCredential(credential)
.addOnCompleteListener(activity) task ->
if (task.isSuccessful)
// Sign in success, update UI with the signed-in user's information
Log.d(Tag, "signInWithCredential:success")
val user = auth.currentUser
activity.shortToast("SignInSuccess")
else
// If sign in fails, display a message to the user.
Log.w(Tag, "signInWithCredential:failure", task.exception)
activity.shortToast("SignInFailed")
fun signInGoogle(activity: Activity)
val signInIntent = googleSignInClient.signInIntent
activity.startActivityForResult(signInIntent, Constants.RC_SIGN_IN)
fun signOutGoogle(activity: Activity)
googleSignInClient.signOut().addOnCompleteListener(activity)
//Update ui
【问题讨论】:
看看 Paha 实现 GoogleSignIn 的实现:github.com/jojink/Android-Kotlin-FirebaseAuth/blob/feature/…希望这会有所帮助。 那个 git 看起来更像 MVP no MVVM 如果您对干净的 Firebase 身份验证感兴趣,可以查看此article。 在 codelab github.com/googlecodelabs/android-kotlin-logingoogle 上查看这个例子 你好@ELTEGANIMOHAMED!谢谢 !这正是我想要的:) 【参考方案1】:这是我所做的。
创建用户模型:
data class User(
val uid: String,
val name: String?,
val email: String?,
var isAuthenticated: Boolean = false,
var isNew: Boolean? = false,
var isCreated: Boolean = false
) : Serializable
constructor() : this("","","")
创建 AuthRepository 类:
class AuthRepository
private val firebaseAuth: FirebaseAuth = FirebaseAuth.getInstance()
private val rootRef: FirebaseFirestore = FirebaseFirestore.getInstance()
private val usersRef: CollectionReference = rootRef.collection(USERS)
// Sign in using google
fun firebaseSignInWithGoogle(googleAuthCredential: AuthCredential): MutableLiveData<ResponseState<User>>
val authenticatedUserMutableLiveData: MutableLiveData<ResponseState<User>> =
MutableLiveData()
firebaseAuth.signInWithCredential(googleAuthCredential).addOnCompleteListener authTask ->
if (authTask.isSuccessful)
var isNewUser = authTask.result?.additionalUserInfo?.isNewUser
val firebaseUser: FirebaseUser? = firebaseAuth.currentUser
if (firebaseUser != null)
val uid = firebaseUser.uid
val name = firebaseUser.displayName
val email = firebaseUser.email
val user = User(uid = uid, name = name, email = email)
user.isNew = isNewUser
authenticatedUserMutableLiveData.value = ResponseState.Success(user)
else
authenticatedUserMutableLiveData.value = authTask.exception?.message?.let
ResponseState.Error(it)
return authenticatedUserMutableLiveData
创建 LoginViewModel 类:
class LoginViewModel constructor(private val authRepository: AuthRepository) :
ViewModel()
private var _authenticateUserLiveData: MutableLiveData<ResponseState<User>> = MutableLiveData()
val authenticateUserLiveData: LiveData<ResponseState<User>> get() = _authenticateUserLiveData
fun signInWithGoogle(googleAuthCredential: AuthCredential)
_authenticateUserLiveData = authRepository.firebaseSignInWithGoogle(googleAuthCredential)
这里的ResponseState类如下:
sealed class ResponseState<T>(
val data: T? = null,
val message: String? = null
)
class Success<T>(data: T) : ResponseState<T>(data)
class Error<T>(message: String) : ResponseState<T>(message = message)
class Loading<T> : ResponseState<T>()
在您的活动或片段中,您可以将其用作:
lateinit var googleSignInClient: GoogleSignInClient
private fun initGoogleSignInClient()
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
private fun signInUsingGoolge()
val signInGoogleIntent = (activity as MainActivity).googleSignInClient.signInIntent
startActivityForResult(signInGoogleIntent, RC_SIGN_IN)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent ? )
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RC_SIGN_IN)
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
try
// Google Sign In was successful, authenticate with Firebase
val account = task.getResult(ApiException::class.java) !!
if (account != null)
getGoogleAuthCredential(account)
catch (e: ApiException)
// Google Sign In failed, update UI appropriately
private fun getGoogleAuthCredential(account: GoogleSignInAccount)
binding.progressBar.visible()
val googleTokeId = account.idToken
val googleAuthCredential = GoogleAuthProvider.getCredential(googleTokeId, null)
signInWithGoogleAuthCredential(googleAuthCredential)
private fun signInWithGoogleAuthCredential(googleAuthCredential: AuthCredential)
loginViewModel.signInWithGoogle(googleAuthCredential)
loginViewModel.authenticateUserLiveData.observe(viewLifecycleOwner,
authenticatedUser - >
when(authenticatedUser)
is ResponseState.Error - >
authenticatedUser.message ? .let
context ? .toast(it)
is ResponseState.Success - >
if (authenticatedUser.data != null)
//update ui
is ResponseState.Loading - >
//show progress
)
【讨论】:
以上是关于如何构建Android MVVM应用程序的主要内容,如果未能解决你的问题,请参考以下文章
《Android构建MVVM》系列 之 MVVM架构快速入门
Android MVVM startActivity 的最佳实践
使用Architecture Components构建的应用程序是否使其成为“MVVM”,如果是,应用程序的哪些部分与哪个MVVM层相关?