Android flavor - cannot find symbol variable in R file

我是研究僧i 提交于 2019-12-06 23:45:47

问题


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;
}

回答1:


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.




回答2:


Can you put your paidbutton XML tag and your MainActivity.java class imports please.

You are maybe using the wrong resource import like import android.R; instead of import my_package.R;




回答3:


You need your if clause in the on create and then add the setContentView, so somethin like this:

if (BuildConfig.FLAVOR.equals("paidapp")) {
        setContentView(R.layout.activity_main_paid);
        View paidbutton = findViewById(R.id.paidbutton);
        paidbutton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //...
            }
        });
}
else{
    setContentView(R.layout.activity_main_free);
}

or you could possibly use one layout for both and just make the button invisible

I hope this helps



来源:https://stackoverflow.com/questions/27312897/android-flavor-cannot-find-symbol-variable-in-r-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!