1

J'ai une application qui a 3 saveurs différentes, full, part1 et part2.Comment cacher ou ajouter des éléments de menu pour Flavour?

Tous les différents goûts ont des noms de paquets différents, donc je peux les expédier en différentes applications.

Maintenant, je veux que seulement part1 obtienne un élément de menu appelé Reload. Les 2 autres saveurs ne devraient pas avoir cet élément de menu. Est-ce possible?

J'ai essayé les suivantes avec les ressources du menu:

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

main_activity.xml pour part1 est:

<?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> 

Et main_activity.xml pour main est:

<?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> 

Cependant, si je construire l'ap p dans une autre variante de construction que part1, je reçois une erreur de compilation dans mon MainActivity où je dois réagir à la sélection du menu:

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

Il est bien évident pourquoi. Mais avez-vous une suggestion quant à la solution pour personnaliser les menus pour différentes saveurs de construction?

+1

vous pourriez avoir une BaseActivity avec le code commun et différentes MainActivity par saveur, où vous fournissez une version différente de 'onOptionsItemSelected' – Blackbelt

Répondre

1

Créez un MainActivity dans le dossier source principal dans lequel vous gérez le code commun normal. Créez un autre MainActivity dans le dossier source part1 où vous remplacez onOptionsItemSelected où il n'est pas un problème pour avoir des références à R.id.action_reload. Cela devrait fonctionner.

0

Vous pouvez définir le contenu de la méthode onOptionsItemSelected(MenuItem item) dans une aide, puis en utilisant des saveurs charger l'aide nécessaire:

@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 
    } 
} 
1

Vous pouvez également créer un autre fichier xml dans le dossier de menu et de créer le même identifiant de ressource à l'intérieur Par exemple:

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

Ensuite, dans le menu fictif, créez un élément avec le même ID. Vous ne l'utiliserez tout simplement pas car il ne sera jamais sélectionné, car il n'a jamais été gonflé.

+0

... ce n'est pas un mauvais nswer soit. Les deux réponses que j'ai commentées sont meilleures que la réponse acceptée – SimonH

+0

J'ai récemment lu une autre réponse qui pourrait résoudre le même problème: Vous pouvez ajouter un fichier ids.xml dans le dossier de valeurs, où vous pouvez déclarer seulement l'ID, et Comme je l'ai déjà dit, ne l'utilise jamais vraiment. – Omaraf

6

Si vous ne voulez pas copier le fichier toute la classe, mais pour détecter la saveur ou la mise pour toute la saveur et l'ajuster font alors ceci:

Dans le fichier gradle créer champ config:

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

puis construisez gradle. Vous pouvez accéder à ce champ de configuration dans l'activité comme ceci:

@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); 
} 
+1

À mon humble avis, c'est une bien meilleure réponse. Il est beaucoup plus facile de créer toutes les options de votre menu, puis de supprimer celles dont vous n'avez pas besoin dans votre produit, plutôt que d'avoir différentes versions de MainActivity. – SimonH

2

Il y a une autre façon - créer un fichier de valeur avec des ressources booléenne, avec une valeur différente pour chaque saveur, par exemple:

principale/res/valeurs/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> 

puis dans le menu reource définir la valeur de la visibilité dépend des ressources:

<menu ..> 
    <item .. 
     android:visible="@bool/show_reload" 
     .. 
    /> 
</menu>