6

我有一个有 3 种不同风格的应用程序fullpart1part2.

所有不同的风格都有不同的包名称,所以我可以将它们作为不同的应用程序发布。

现在我希望它只part1获得一个名为Reload. 其他 2 种口味不应该有这个菜单项。这可能吗?

我尝试了以下菜单资源:

app
|
+-src
  |
  +-full
  |
  +-main
  | |
  | +-res
  |   |
  |   +-menu
  |     |
  |     +-main_activity.xml
  |
  +-part1
  | |
  | +-res
  |   |
  |   +-menu
  |     |
  |     +-main_activity.xml
  |
  +-part2

哪里main_activity.xmlpart1

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_reload"
        android:icon="@drawable/ic_reload"
        android:title="@string/action_reload"
        app:showAsAction="always"/>
</menu>

main_activity.xml对于main是:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
</menu>

但是,如果我在任何其他构建变体中构建应用程序part1,我会在MainActivity需要对菜单选择做出反应的地方出现编译错误:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_reload: // Compile error: This item is not available
            // TODO reload
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

这是很明显的。但是你有什么建议可以为不同的构建风格定制菜单吗?

4

5 回答 5

12

还有另一种方法 - 使用布尔资源创建值文件,每种风格具有不同的值,例如:

主要/res/values/bool.xml :

 <resources>
        <bool name="show_reload">false</bool>
    </resources>

第 1 部分/res/values/bool.xml

    <?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="show_reload">true</bool>
</resources>

然后在您的菜单资源中设置取决于资源的可见性值:

<menu ..>
    <item ..
      android:visible="@bool/show_reload"
      ..
    />
</menu>
于 2017-10-18T07:12:41.720 回答
11

如果您不想复制整个类文件,而是要检测风味或任何风味的设置并进行调整,请执行以下操作:

在 gradle 文件中创建配置字段:

defaultConfig {
    ...
    buildConfigField "boolean", "SHOW_MY_MENU_ITEM", "true"
}
productFlavors {
    FooFlavour {
        ...
        buildConfigField "boolean", "SHOW_MY_MENU_ITEM", "false"
    }
}

然后构建gradle。您可以像这样在 Activity 中访问此配置字段:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.foo_menu, menu);
    if (!BuildConfig.SHOW_MY_MENU_ITEM) {
        MenuItem myItem = menu.findItem(R.id.my_menu_item);
        myItem.setVisible(false);
    }
    return super.onCreateOptionsMenu(menu);
}

类似,但我认为更好的方法是使用 resValue,首先在 gradle 文件中创建它:

defaultConfig {
    ...
    resValue "bool", "show_my_menu_item", "true"
}
productFlavours {
    FooFlavour {
        ...
        resValue "bool", "show_my_menu_item", "false"
    }
}

这个 resValue 之后可以直接在 menu.xml 中访问:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        ...
        android:visible="@bool/show_my_menu_item" />
</menu>
于 2016-12-13T15:46:27.703 回答
2

您还可以在 menu 文件夹中创建另一个 xml 文件,并在其中创建相同的资源 id,例如:

app
|
+-src
  |
  +-full
  |
  +-main
  | |
  | +-res
  |   |
  |   +-menu
  |     |
  |     +-main_activity.xml
  |     +-dummy_menus.xml

然后在虚拟菜单中创建一个具有相同 ID 的项目。您只是不会使用它,因为它永远不会被选中,因为它从未膨胀过。

于 2016-06-13T03:52:59.720 回答
1

在处理普通公共代码的主源文件夹中创建一个MainActivity。在 part1 源文件夹中创建另一个MainActivity,您可以在其中覆盖onOptionsItemSelected引用R.id.action_reload. 那应该行得通。

于 2016-04-12T09:34:55.787 回答
0

您可以onOptionsItemSelected(MenuItem item)在帮助程序中定义方法的内容,然后使用风味加载所需的帮助程序:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    HelperPart.selectItem(this, item);
}


// Helper loaded for flavor "part1"
static class MenuHelper{ 
    public static boolean selectItem(Activity act, MenuItem item){
        switch (item.getItemId()) {
            case R.id.action_reload: 
                // TODO reload
                return true;
            default:
                return act.onOptionsItemSelected(item);
        }
    }
}

// Helper loaded for flavor "part2" and "full"
static class MenuHelper{
    public static boolean selectItem(Activity act, MenuItem item){
        // Do nothing
    }
}
于 2016-04-12T09:40:51.583 回答