【问题标题】:How to call baseactivity function from viewmodel in android如何从android中的viewmodel调用baseactivity函数
【发布时间】:2017-11-06 13:05:14
【问题描述】:

嗨,我有 LoginActivityLoginViewModel 以及更多课程。我在BaseActivity 中有showLoadinghideLoading,因此可以从每个活动中访问它。

我可以像 mNavigator?.startForgotPasswordActivity() 一样从 LoginViewModel 调用 LoginActivity 方法

我想从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
}

【问题讨论】:

    标签: android mvvm kotlin android-viewmodel


    【解决方案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
    

    现在使用导航器,您可以访问基本活动并调用显示/隐藏加载程序功能

    mNavigator!!.getActivity().showLoading()
    

    【讨论】:

      猜你喜欢
      • 2020-02-13
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 1970-01-01
      • 2012-12-07
      • 1970-01-01
      • 2014-04-07
      相关资源
      最近更新 更多