2

I'm new to Kotlin and I started a new Android project using this language. From the beginning I faced some issues when a tried to make a schema of a MVP pattern in Kotlin using generic types. This is what I'm trying to accomplish:

AbstractBasePresenter.kt

abstract class AbstractBasePresenter<T: Any> internal constructor(
    private val compositeDisposable: CompositeDisposable = CompositeDisposable()
) {

    constructor() : this(CompositeDisposable())

    private var view: T? = null

    fun bind(view: T) {
        if (this.view != null) throw IllegalStateException("view already bound")
        this.view = view
        afterBind()
    }

    fun unbind() {
        if (this.view == null) throw IllegalStateException("view already unbound")
        this.view = null
        compositeDisposable.clear()
    }

    abstract fun afterBind()

    protected fun addDisposable(disposable: Disposable): Disposable =
        disposable.also {
            compositeDisposable.add(it)
        }

    protected fun view(): T = view ?: throw IllegalStateException("view not bound")
}

BaseView.kt

interface BaseView<T : AbstractBasePresenter<*>> {

    fun getPresenter(): T
}

AbstractBaseActivity

abstract class AbstractBaseActivity<T : AbstractBasePresenter<*>> : AppCompatActivity(), BaseView<T> {

    override fun onStart() {
        super.onStart()
        getPresenter().bind(this)
    }

    override fun onStop() {
        getPresenter().unbind()
        super.onStop()
    }

    override fun startActivity(intent: Intent?) {
        super.startActivity(intent)
        slideInRight(this)
    }

    override fun onBackPressed() {
        super.onBackPressed()
        slideOutRight(this)
    }
}

When I'm trying to use the base class I want something like bellow:

SplashActivity

class SplashActivity : AbstractBaseActivity<SplashPresenter>(), SplashActivityView {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.splash_activity)
    }

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

SplashPresenter

class SplashPresenter : AbstractBasePresenter<SplashActivityView>() {

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

SplashActivityView

interface SplashActivityView {

}

The idea is that this type of implementation is working fine in Java, but after the conversion it seems that with generic types from Kotlin I'm missing something and I got the following error in AbstractBaseActivity at binding the view:

    **getPresenter().bind(this)** ------> "this" is underlined and I have the error: **"Type mismatch. Required nothing AbstractBaseActivity<T> found"**

Please tell me where I am doing things wrong or give me another type of solution to accomplish the actual BaseActivity scope (bind and unbing from a single place). Thank you!

mrRobot
  • 21
  • 3

0 Answers0