首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Google/Facebook在MVVM中注册

Google/Facebook在MVVM中注册
EN

Stack Overflow用户
提问于 2018-09-12 03:20:24
回答 1查看 4.8K关注 0票数 14

我在我的项目中使用带有数据绑定的MVVM结构。当涉及到GG/FB登录时,事情会变得很奇怪,因为他们需要Context

代码语言:javascript
复制
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,所以我不能将它传递给接收DataBinding事件的ViewModel。

代码语言:javascript
复制
class LoginViewModel(
    dataManager: DataManager,
    schedulerProvider: SchedulerProvider
) : BaseViewModel<LoginNavigator>(dataManager, schedulerProvider) {

    fun loginGoogle(){
        setIsLoading(true)
        //No idea what to write in here
    }
}

是否有任何方式使用Gg/FB登录与MVVM结构?或者我只需要做原来的方法(用Activity做所有的事情)?

EN

回答 1

Stack Overflow用户

发布于 2019-01-20 09:45:30

这很简单,多亏了@Erik Browne和Kotlin的函数文本和接收者

创建SingleLiveEvent

创建LiveMessageEvent

代码语言:javascript
复制
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
    }
}

创建接口

代码语言:javascript
复制
interface ActivityNavigation {
    fun startActivityForResult(intent: Intent?, requestCode: Int)
}

**现在是实施的时候了!**

In LoginViewModel

代码语言:javascript
复制
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)
            )
        }
    }

在您的LoginActivtyImplement ActivityNavigation接口

代码语言:javascript
复制
//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)
}

#遵循这种方法可以确保LoginViewModel在视图(LoginActivity)和模型(GoogleSignInClient)之间建立链接,并且视图只负责显示UI事件。

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52287013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档