Home » Android » Android DataBinding custom adapter in multiple modules-Exceptionshub

Android DataBinding custom adapter in multiple modules-Exceptionshub

Posted by: admin February 24, 2020 Leave a comment

Questions:

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"
            }
        }
    }
}
How to&Answers:

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.

Answer:

I think this be difference of implementation and api in gradle.
When you use implementation for A and you can use that modules and when use api your app is depend on A and all its dependencies like B.