0

I want to refactor the following code so that I can reuse it with different ViewHolder types:

class TestsAdapter(
    private val clickListener: ClickListener
) : PagedListAdapter<RecyclerViewTestInfo, TestsViewHolder>(diffCallback) {

    override fun getItemCount(): Int {
        return super.getItemCount()
    }

    override fun onBindViewHolder(holder: TestsViewHolder, position: Int) {
        val testInfo = getItem(position) as RecyclerViewTestInfo

        with(holder) {
            bindTo(testInfo)
            testInfo.let {
                itemView.setOnClickListener {
                    clickListener(testInfo)
                }
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TestsViewHolder =
        TestsViewHolder(parent)
}

It isn't clear to me though how you handle the creation of an instance for a generic type. In the code, onCreateViewHolder is initialized with a specific ViewHolder. How would I do this with a generic?

1 Answer 1

1

The problem you are facing here is that you can't directly initialize an instance from a generic type, you need to have at least a Class object. There is a solution, however I wouldn't recommend to use it, since it adds an undesirable layer of complexity.

Pass class type to constructor:

   class Test<A : DiffUtil.Callback, B : RecyclerView.ViewHolder?>(type: Class<B>): PagedListAdapter<A, B>(diff)

There using reflection you will be able to create a new instance, however you need to know exactly the constructor, for example in your case you have a constructor with a single parameter of ViewGroup type:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): B =
    type.getConstructor(ViewGroup::class.java).newInstance(parent)

This solution is undesirable, since there are no compile-time checks and when someone will create a new ViewHolder with a different constructor he will get a runtime error.

Sign up to request clarification or add additional context in comments.

Comments

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.