Как скрыть или добавить пункты меню для Flavor?

У меня есть приложение, которое имеет 3 разных вкуса, full, part1 а также part2,

Все разные вкусы имеют разные названия пакетов, поэтому я могу поставлять их как разные приложения.

Теперь я хочу только этого part1 получает пункт меню под названием Reload, Другие 2 вкуса не должны иметь этого пункта меню. Это возможно?

Я попробовал следующее с ресурсами меню:

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

куда main_activity.xml за part1 является:

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

Совершенно очевидно, почему это так. Но есть ли у вас какие-либо предположения о том, что решение состоит в том, чтобы настроить меню для различных вариантов сборки?

5 ответов

Решение

Создать MainActivity в основной папке с исходным кодом, где вы обрабатываете обычный общий код. Создать другой MainActivity в исходной папке part1, где вы переопределяете onOptionsItemSelected где не проблема иметь ссылки на R.id.action_reload, Это должно работать.

Есть другой способ - создать файл значений с логическим ресурсом, с разными значениями для каждого варианта, например:

main /res/values/bool.xml:

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

part1 /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>

Если Вы не хотите копировать весь файл класса, но хотите обнаружить аромат или настройку для любого аромата и настроить его, то сделайте это:

В файле 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);
}

Вы также можете создать еще один XML-файл в папке меню и создать в нем тот же идентификатор ресурса, например:

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

А затем в фиктивном меню создайте элемент с таким же идентификатором. Вы просто не будете использовать его, потому что он никогда не будет выбран, так как он никогда не был раздут.

Вы можете определить содержание 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
    }
}
Другие вопросы по тегам