0

I have the following Java class I'm trying to convert to Kotlin that uses generics.

abstract class MvpViewHolder, M, V : View?>(itemView: View) : RecyclerView.ViewHolder(itemView) {

public abstract class MvpViewHolder<P extends BasePresenter> extends RecyclerView.ViewHolder {
    protected P presenter;

    public MvpViewHolder(View itemView) {
        super(itemView);
    }

    public void bindPresenter(P presenter) {
        this.presenter = presenter;
        presenter.bindView(this);
    }

    public void unbindPresenter() {
        presenter = null;
    }
}

Here is my Kotlin attempt

abstract class MvpViewHolder<P : BasePresenter>(itemView: View) : RecyclerView.ViewHolder(itemView) {

    protected var presenter: P? = null

    fun bindPresenter(presenter: P?): Unit {
        this.presenter = presenter
        presenter?.bindView(this)

    }

    fun unbindPresenter(): Unit {
        this.presenter = null
    }
}

I'm particularly running into a problem with the generics. It turns out that in Kotlin it's simply not enough to do MvpViewHolder<P : BasePresenter> as Kotlin requires that we pass in the 2 type arguments for BasePresenter (whose implementation I put below)

However, if I need to pass in the type arguments for BasePresenter then my method signature would then look like this

`abstract class MvpViewHolder<P : BasePresenter<*, *>>(itemView: View) : RecyclerView.ViewHolder(itemView) {`

This does not help me however, because in presenter.bindView(this) I get a type error of Required: Nothing, Found: MvpViewHolder

I could also get more specific and pass in MvpViewHolder<P: BasePresenter<M, V>, M, V> but then that would mean that wherever I call MvpViewHolder, I then also have to include 2 extra type parameters. Not only will that be tedious to deal with now having to maintain, but it just makes me sad.

How can I either get rid of the error when I use BasePresenter<,> or avoid having to pass in 3 type parameters into my MvpViewHolder class, just so I can define P as a BasePresenter

abstract class BasePresenter<M, V> {
    var model: M? = null

    var view: WeakReference<V>? = null

    fun setM(model: M?): Unit {
        this.model = model

        if (setupDone()) {
            updateView()
        }
    }

    fun bindView(view: V) {
        this.view = WeakReference(view)
    }

    fun unbindView() {
        this.view = null
    }

    abstract fun updateView()

    fun view(): V? {
        return if (view == null) null else view?.get()
    }

    fun setupDone(): Boolean {
        return view() != null && model != null
    }

}

1 Answer 1

1

Change abstract class to the following code

 abstract class MvpViewHolder<P :BasePresenter<P,MvpViewHolder<P>>>(itemView: View) : RecyclerView.ViewHolder(itemView) {
        protected var presenter: P? = null
        fun bindPresenter(presenter: P) {
            this.presenter = presenter
            presenter.bindView(this)
        }

        fun unbindPresenter() {
            presenter = null
        }
    }
Sign up to request clarification or add additional context in comments.

6 Comments

what would happen to a class that extends MvpViewHolder? How would I pass in a parameter to that? open class VenuesViewHolder(itemView: View) : MvpViewHolder<VenuePresenter>(itemView), VenueView here is an example. VenuePresenter, which extends BasePresenter throws an error that it's not within its bounds
I can turn this into another question if you wish
open class VenuesViewHolder<M,P:BasePresenter<P, MvpViewHolder<P>>>(itemView: View) : MvpViewHolder<P>(itemView) Your presenter will look like below class VenuePresenter<P:BasePresenter<P, MvpViewHolder<P>>,M:MvpViewHolder<P>> :BasePresenter<P,M>(){ override fun updateView() { }
What is the pattern here? Is there any resource that you're using?
I am just referring Java generics and kotlin generics. Error can be corrected by just seeing the error message from ide itself
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.