I have 2 flavors - paidapp and freeapp.
The only difference that paidapp have 1 more button on MainActivity
, say "paidbutton"
.
paidapp has its own layout with button android:id="@+id/paidbutton"
and layout for freeapp does not have this button.
In code I use this:
if (BuildConfig.FLAVOR.equals("paidapp")) {
View paidbutton = findViewById(R.id.paidbutton);
paidbutton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//...
}
});
}
But I have an error cannot find symbol variable
in findViewById(R.id.paidbutton);
How to solve this problem without cloning MainActivity.java in both flavors?
EDIT1 - add more code examples:
Gradle:
productFlavors {
paidapp {
}
freeapp {
}
}
/app/src/main/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/goNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go next" />
</LinearLayout>
/app/src/paidapp/res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/goNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Go next" />
<Button
android:id="@+id/paidbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="See more" />
</LinearLayout>
/app/src/main/java/company/com/myapplication/MainActivity.java
package company.com.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View goNext = findViewById(R.id.goNext);
goNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "goNext click", Toast.LENGTH_SHORT).show();
}
});
if (BuildConfig.FLAVOR.equals("paidapp")) {
View paidbutton = findViewById(R.id.paidbutton);
paidbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "paidapp click", Toast.LENGTH_SHORT).show();
}
});
}
}
}
EDIT2 - I have found some workaround using reflection, but still looking for normal solution:
instead of View paidbutton = findViewById(R.id.paidbutton);
I have used View paidbutton = findViewById(getIdFromRId("paidbutton"));
where getIdFromRId
is:
private int getIdFromRId(String idName) {
int id = 0;
try {
Class c = R.id.class;
Field field = c.getField(idName);
id = field.getInt(null);
} catch (Exception e) {
// do nothing
}
return id;
}
If you don't have paidbutton
layout element at all in the freeapp
product flavor, you can just declare corresponding id item in one of your resource xml files in freeapp
product flavor folder. For example create the file src/freeapp/res/values/ids.xml
containing:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="paidbutton" type="id"/>
</resources>
After doing that you'll have no problems with compiling common code since the symbol R.id.paidbutton
will be defined for both product flavors. findViewById()
call will return the real layout element in paidapp
build and will return null in freeapp
build.