user20958695
user20958695

Reputation: 23

Flavor specific views not compiling under other build variants

I have one MainActivity.java activity, one main.xml file and multiple flavors, each flavor having its own version of main.xml which gets priority over the main flavor's main.xml file, and each flavor has its unique views.

The problem is that when choosing some build variant (some flavor) the other flavors' unique views don't compile ('cannot find symbol') on their findViewById(R.id.someflavorUniqueViewId) because clearly they are not existing in this flavor.

The solution I found was to make some 'dummy views' that are empty so that all views appear in all flavors and this solves it, but it's messy and if I would have a lot of flavors, then any update of some flavor to contain a new view would require adding these 'dummy views' in all corresponding layout files, which doesn't make much sense.

Is there a better solution for this problem?

Was hoping for something like this but couldn't find a way to do it:

if (viewExists("someFlavorUniqueViewName")) {
    int flavorUniqueId = getViewId("someFlavorUniqueViewName");
    View flavorUniqueView = findViewById(flavorUniqueId);
}

Edit: I found how to solve it programmatically:

if (BuildConfig.FLAVOR.equals("someFlavor")) {
    int flavorUniqueId = getResources().getIdentifier("someFlavorUniqueViewName", "id", getPackageName());
    View flavorUniqueView = findViewById(flavorUniqueId);
    // do something...
}

I believe this has a slight efficiency drawback versus the XML solution in Ruslan's answer, but I ended up using this one since I was actually updating a huge code base and didn't want to change too much there. So in case anyone facing this problem, this is another solution.

Upvotes: 0

Views: 63

Answers (1)

Ruslan
Ruslan

Reputation: 1059

You can declare all Flavor dependant IDs beforehand under values/ids.xml as follows:

<?xml version="1.0" encoding="utf-8"?>
<resources>
...
   <item type="id" name="someflavorUniqueViewId1"/>
...
</resources>

And in xml layout files you can assign IDs which you already declared, e.g.

<androidx.cardview.widget.CardView
            android:id="@id/someflavorUniqueViewId1" ...

Please note that I'm using @id and not @+id. That is because ID is already declared in ids.xml, so we don't need to create a new one.

After that you could check your build Flavor in runtime and act accordingly.

@Nullable View optionalView1;

if (BuildConfig.FLAVOR.equals("flavor1")) {
    optionalView1 = findViewById(R.id.someflavorUniqueViewId1);
}
        

You just mark all Flavor dependant views as @Nullable, so IDE will help you not to forget to check for null in places where it is needed.

Also, please consider switching to ViewBinding, it has some advantages over finding view manually by id.

Upvotes: 0

Related Questions