1

I had a function that used a view that could handle two different layouts because the two layouts have the same resources names. I am updating the code to use databindings, but I would like to keep using the generic function that is able to handle both layouts rather than splitting it into two functions for the two different bindings. I originally thought that I could do so using DataBindingUtil like so:

fun LoadChatMessage(context: Context, itemView: View, itemID: Int, item: Chat) {
    val itemBinding = DataBindingUtil.inflate(LayoutInflater.from(context), itemID, itemView as ViewGroup, false)
}

In this scenario, itemID is the layoutId of the two layouts, either R.layout.chat_1 or R.layout.chat_2 (example names). However, I can't use this because it is considered to be not enough information to inflate DataBindingUtil. I tried hardcoding the layoutIds instead, and that was not the issue. The only way to fix the error message was by declaring itemBinding as an ItemChat1Binding or an ItemChat2Binding, but this is the very issue I was trying to avoid because I won't know which databinding to use until the function is called.

Is there any way to keep this generic format so I can plug in the corresponding layout to the function since the layouts use the same resource names?

1 Answer 1

1

Short answer: I recommend writing the code for both individually, not using databinding for this, or taking a look and seeing if it really makes sense to have your layouts this way.

Long answer: Without more details and trying to recreate the situation on my own, I'm going to say that what you want to do is either not possible or incredibly unconventional. Data/View binding generates classes at build time based off of your xml that include fields/properties that correspond to the various xml properties. This means each one is uniquely tied to a specific xml and won't know anything about other xml files.

There might be some hope with what is known as a generic/template. Rather than writing the same code multiple times the only difference being the type, you can write the code once but with a sort of 'placeholder' type, often T.

For example

fun <T: ViewDataBinding> LoadChatMessage(context: Context, itemView: View, itemID: Int, item: Chat) {
    val itemBinding: T = DataBindingUtil.inflate(LayoutInflater.from(context), itemID, itemView as ViewGroup, false)
}

However, I don't think this will allow you to do what it sounds like you want to do. This is because the closest that the code can get to knowing what type T is, is that it is a ViewDataBinding. It will not have any access to the properties that ItemChat1Binding or ItemChat2Binding will have.

The only thing I can think of that would sort of work is a massive work around requiring you to write a wrapper for a ViewDataBinding, but I recommend against that. I am questioning why you want to have 2 different layouts/views with the same resource names rather than one layout/view with a high level of flexibility.

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.