如何从android中的viewmodel调用baseactivity函数

时间:2017-11-06 13:05:15

标签: android mvvm kotlin android-viewmodel

您好我有LoginActivityLoginViewModel以及更多课程。我在showLoading中有hideLoadingBaseActivity,因此可以从每个活动访问它。

我可以从LoginActivity LoginViewModel

调用mNavigator?.startForgotPasswordActivity() 方法

我想从LoginViewModel调用它然后用MVVM做什么?或者我的做法是错误的。请建议这样做的正确方法是什么?

BaseActivity.kt

abstract class BaseActivity : AppCompatActivity(), AnkoLogger {

    private val progressBar: ProgressBar? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }

    protected fun getToolbar(): Toolbar {
        val toolbar: Toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)
        return toolbar
    }

    protected fun performDependencyInjection() {
        AndroidInjection.inject(this);
    }

    @TargetApi(Build.VERSION_CODES.M)
    fun requestPermissionsSafely(permissions: Array<String>, requestCode: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(permissions, requestCode)
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    fun hasPermission(permission: String): Boolean {
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.M || checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED
    }

    fun isNetworkConnected(): Boolean {
        return NetworkUtils.isNetworkConnected(applicationContext)
    }

    fun showLoading() {
        hideLoading()
        // show progress bar
    }

    fun hideLoading() {
        // hide progress bar
    }

}

LoginActivity.kt

class LoginActivity : BaseActivity(), LoginNavigator {

    @Inject
    lateinit var loginViewModel: LoginViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        performDependencyInjection()
        super.onCreate(savedInstanceState)
        val activityLoginBinding: ActivityLoginBinding = DataBindingUtil.setContentView<ActivityLoginBinding>(this, R.layout.activity_login)
        activityLoginBinding.loginViewModel = loginViewModel
        loginViewModel.mNavigator = this
    }

    override fun startHomeActivity() {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

    override fun startRegistrationActivity() {
        startActivity(Intent(this, RegistrationActivity::class.java))
    }

    override fun startForgotPasswordActivity() {
        startActivity(Intent(this, ForgotPasswordActivity::class.java))
    }

    override fun handleError(throwable: Throwable) {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }

}

LoginViewModel.kt

class LoginViewModel : BaseViewModel<LoginNavigator>(), AnkoLogger {

    val emailField = ObservableField<String>()

    private val email: String
        get() = emailField.get()

    val passwordField = ObservableField<String>()

    private val password: String
        get() = passwordField.get()

    @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
    fun login(view: View) {
        if (isEmailAndPasswordValid(email, password)) {
            ApiHelperImpl().doServerLoginApiCall(email, password)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeWith(object : CallbackWrapper<LoginResponse>() {

                        override fun onSuccess(loginResponse: LoginResponse) {
                            info { loginResponse }
                        }
                    })
        }
    }

    /**
     * Validate email and password. It checks email and password is empty or not
     * and validate email address is correct or not
     * @param email email address for login
     * @param password password for login
     * @return true if email and password pass all conditions else false
     */
    private fun isEmailAndPasswordValid(email: String, password: String): Boolean {

        if (email.isEmpty()) return false

        if (!Patterns.EMAIL_ADDRESS.matcher(email).matches()) return false

        if (password.isEmpty()) return false

        return true
    }

}

BaseViewModel.kt

abstract class BaseViewModel<N> {
    var mNavigator: N? = null
}

1 个答案:

答案 0 :(得分:1)

同样的

可以有两种方法

1)根据mvp从视图(Activity或Fragment)使用与UI更新或UI事件监听器相关的所有功能,并且仅从viewmodel尝试管理api和其他逻辑等数据

class LoginActivity : BaseActivity(), LoginNavigator {

    @Inject
    lateinit var mLoginViewModel: LoginViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        mLoginViewModel.mNavigator = this

        callApi()
    }

    private fun callApi() {
        showLoading()
        mLoginViewModel.callApi()
    }

    override fun openHomeScreen(model: Model) {
        hideLoading()
        showSnackBar(constraint_root, model.Domain)
    }

}


class LoginViewModel(sessionManager: SessionManager, requestInterface: RequestInterface) : BaseViewModel<LoginNavigator>(sessionManager, requestInterface) {

    fun callApi() {
        requestInterface.getServiceIP()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(this::handleResponse, this::handleError)
    }

    private fun handleResponse(model: Model) {
        if (model.Domain == null) {
            mNavigator!!.openHomeScreen(model)
        } else {

        }
    }

    private fun handleError(error: Throwable) {
        error.printStackTrace()
    }
}

2) 在登录界面添加功能

interface LoginNavigator {
    fun openHomeScreen()
    fun getActivity(): BaseActivity
}

在LoginActivity中覆盖该函数并返回

override fun getActivity(): BaseActivity = this

现在使用导航器,您可以访问基本活动&amp;呼叫显示/隐藏加载器功能

mNavigator!!.getActivity().showLoading()