Как скрыть или добавить пункты меню для 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
}
}