Search code examples
androidandroid-databinding

Android DataBinding custom adapter in multiple modules


Context

I have 3 modules: A, B, and app. app depends on A, and A depends on B.

Custom data binding adapters are in B.

app -> A -> B

All modules have data binding enabled, as well as kapt plugin.

plugins {
    kotlin("kapt")
}

android {
    dataBinding.isEnabled = true
}

Problem

Let's say I have the following binding adpater function:

@BindingAdapter("fontWeight")
fun TextView.setFontWeight(family: String)

In app, I can use it as an extension function, but cannot use it as a custom binding adapter.

textView.setFontWeight("bold") // It works

<TextView
  app:fontWeight='@{"bold"}' // It doesn't work

What's interesting is that If I make app module directly depends on B, then the binding adapter works as expected.

app -> B

What's the problem? Do you have any ideas? Thanks in advance.

Update

When I remove this lines of code from build.gradle.kts it works properly, but I cannot figure out what's going on.

flavorDimensions("dimension")

productFlavors {
    create("dev")
    create("staging")
    create("production")

    forEach { flavor ->
        with(flavor) {
            dimension = "dimension"
            versionCode = generateVersionCode(name)
            versionName = generateVersionName(name)

            if (name != "production") {
                applicationIdSuffix = ".$name"
            }
        }
    }
}

Solution

  • The problem is that I used same package name in AndroidManifest.xml for both module A and module B.

    <!-- AndroidManifest.xml in Module A -->
    <manifest package="co.riiid.santa.design" />
    
    <!-- AndroidManifest.xml in Module B -->
    <manifest package="co.riiid.santa.design" />
    

    Changing package name of module B solves the problem.

    <!-- Append "components" at the end -->
    <manifest package="co.riiid.santa.design.components" />
    

    I didn't expect that it might cause a problem..


    I'm not sure why it causes the problem, but here's my guess:

    Annotation processing tool kapt generates a class DataBinderMapperImpl for each module that has enabled data binding. The resulting class is located in the package where one specified in AndroidManifest.xml

    Package structure for reference

    Hence if there're modules which have the same package name, a conflict occurs.