谷歌/Facebook 登录 MVVM [英] Google/Facebook Sign In in MVVM
问题描述
我在我的项目中使用 MVVM 结构和数据绑定.当涉及到 GG/FB 登录时,事情变得很奇怪,因为他们需要 Context
I'm using MVVM structure with Data Binding in my project. Things get weird when it comes to GG/FB Sign In, because they need Context
googleApiClient = new GoogleApiClient.Builder(context)
.enableAutoManage(this, this)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
startActivityForResult(signInIntent, GOOGLE_AUTH);
GoogleApiClient
需要 Context
所以我不能把它传递给 ViewModel,它接收 DataBinding 事件.
GoogleApiClient
needs Context
so I can't pass it to ViewModel, which receives DataBinding events.
class LoginViewModel(
dataManager: DataManager,
schedulerProvider: SchedulerProvider
) : BaseViewModel<LoginNavigator>(dataManager, schedulerProvider) {
fun loginGoogle(){
setIsLoading(true)
//No idea what to write in here
}
}
有什么方法可以使用带有 MVVM 结构的 Gg/FB 登录?或者我只需要按照原来的方式(在 Activity
中做所有事情)?
Is there any way to use Gg/FB Sign In with MVVM structure ? Or I just have to do the original way (do everything in Activity
) ?
推荐答案
非常简单,感谢 @Erik Browne 和 Kotlin 的带有接收器的函数字面量
It is very simple thanks to @Erik Browne and Kotlin’s Function literals with receiver
创建 单个直播事件
创建 LiveMessageEvent
Create LiveMessageEvent
class LiveMessageEvent<T> : SingleLiveEvent<(T.() -> Unit)?>() {
fun setEventReceiver(owner: LifecycleOwner, receiver: T) {
observe(owner, Observer { event ->
if ( event != null ) {
receiver.event()
}
})
}
fun sendEvent(event: (T.() -> Unit)?) {
value = event
}
}
创建界面
interface ActivityNavigation {
fun startActivityForResult(intent: Intent?, requestCode: Int)
}
** 现在是实施的时候了!**
在您的 LoginViewModel
const val GOOGLE_SIGN_IN : Int = 9001
class LoginViewModel @Inject constructor(
private val loginRepository: LoginRepository,
private val googleSignInClient: GoogleSignInClient
): ViewModel() {
val startActivityForResultEvent = LiveMessageEvent<ActivityNavigation>()
..
//Called on google login button click
fun googleSignUp() {
val signInIntent = googleSignInClient.signInIntent
startActivityForResultEvent.sendEvent { startActivityForResult(signInIntent, GOOGLE_SIGN_IN) }
}
//Called from Activity receving result
fun onResultFromActivity(requestCode: Int, resultCode: Int, data: Intent?) {
when(requestCode) {
GOOGLE_SIGN_IN -> {
val task = GoogleSignIn.getSignedInAccountFromIntent(data)
googleSignInComplete(task)
}
..
}
}
private fun googleSignInComplete(completedTask: Task<GoogleSignInAccount>) {
try {
val account = completedTask.getResult(ApiException::class.java)
account?.apply {
// .. Store user details
emitUiState(
showSuccess = Event(R.string.login_successful)
)
}
}catch (e: ApiException) {
emitUiState(
showError = Event(R.string.login_failed)
)
}
}
在您的 LoginActivity[实现 ActivityNavigation 界面]
//Called from onCreate once the ViewModel is initialized.
private fun subscribeUi() {
//this sets the LifeCycler owner and receiver
viewModel.startActivityForResultEvent.setEventReceiver(this, this)
..
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
viewModel.onResultFromActivity(requestCode,resultCode,data)
super.onActivityResult(requestCode, resultCode, data)
}
这篇关于谷歌/Facebook 登录 MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!