9

我有 2 种口味 - 付费应用和免费应用。支付应用程序的唯一区别是多了 1 个MainActivity按钮"paidbutton"。paidapp 有自己的带有按钮的android:id="@+id/paidbutton"布局,而 freeapp 的布局没有这个按钮。

在代码中我使用这个:

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

cannot find symbol variable但我有一个错误findViewById(R.id.paidbutton);

如何在不克隆两种风格的 MainActivity.java 的情况下解决这个问题?

EDIT1 - 添加更多代码示例:

摇篮:

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 - 我找到了一些使用反射的解决方法,但仍在寻找正常的解决方案:

而不是View paidbutton = findViewById(R.id.paidbutton);我用过View paidbutton = findViewById(getIdFromRId("paidbutton"));

哪里getIdFromRId是:

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

3 回答 3

23

如果产品风味中根本没有paidbutton布局元素freeapp,则只需在freeapp产品风味文件夹中的资源 xml 文件之一中声明相应的 id 项即可。例如创建包含以下内容的文件src/freeapp/res/values/ids.xml

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

这样做之后,编译通用代码就没有问题了,因为符号R.id.paidbutton将为两种产品风格定义。findViewById()call 将在构建中返回真正的布局元素,并在paidapp构建中返回 null freeapp

于 2015-03-30T09:11:04.230 回答
1

你能把你的付费按钮 XML 标记和你的 MainActivity.java 类导入吗?

您可能使用了错误的资源导入import android.R;,例如import my_package.R;

于 2014-12-05T09:50:48.097 回答
1

您需要在 on create 中使用 if 子句,然后添加 setContentView,因此如下所示:

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

或者您可以对两者都使用一种布局,而只是使按钮不可见

我希望这有帮助

于 2014-12-05T09:53:00.397 回答