1

Ich habe eine App, die 3 verschiedene Geschmacksrichtungen hat, full, part1 und part2.Wie können Menüpunkte für Flavor versteckt oder hinzugefügt werden?

Alle verschiedenen Geschmacksrichtungen haben unterschiedliche Paketnamen, daher kann ich sie als verschiedene Apps versenden.

Jetzt möchte ich, dass nur part1 einen Menüpunkt Reload ruft. Die anderen 2 Geschmacksrichtungen sollten diesen Menüpunkt nicht enthalten. Ist das möglich?

versuchte ich folgendes mit den Menü Ressourcen:

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

Wo main_activity.xml für part1 ist:

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

Und main_activity.xml für main ist:

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

Allerdings, wenn ich baue die ap p in einer anderen Build-Variante als part1, erhalte ich einen Kompilierungsfehler in meinem MainActivity wo ich brauche, um die Menüauswahl zu reagieren:

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

Es ist ziemlich offensichtlich, warum das so ist. Aber haben Sie Vorschläge, wie Sie Menüs für verschiedene Build-Flavors anpassen können?

+1

Sie könnten haben Sie eine BaseActivity mit dem gemeinsamen Code und verschiedenen MainActivity pro Flavor, wo Sie eine andere Version von onOptionsAtemSelected – Blackbelt

Antwort

1

Erstellen Sie einen MainActivity im Hauptquellordner, in dem Sie den normalen gemeinsamen Code verarbeiten. Erstellen Sie einen weiteren MainActivity im Quellordner part1, in dem Sie onOptionsItemSelected überschreiben, wo es kein Problem ist, Referenzen auf R.id.action_reload zu haben. Das sollte funktionieren.

0

Sie können den Inhalt der onOptionsItemSelected(MenuItem item) Methode in einem Helfer definieren und laden Sie dann mit Aromen den benötigten Helfer:

@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

Sie auch in einer anderen XML-Datei im Menü Ordner und erstellen Sie die gleiche Ressource-ID erstellen es zum Beispiel:

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

Und dann in dem Dummy-Menü ein Element mit der gleichen ID erstellen. Sie werden es nicht benutzen, weil es nie ausgewählt wird, da es nie aufgeblasen wurde.

+0

liefern ... das ist kein schlechtes a nswer entweder. Beide Antworten, die ich kommentiert habe, sind besser als die angenommene Antwort – SimonH

+0

Ich habe vor kurzem eine andere Antwort gelesen, die das gleiche Problem lösen könnte: Sie können eine ids.xml-Datei im Werte-Ordner hinzufügen, wo Sie nur die ID deklarieren können wie ich schon gesagt habe, benutze es nie wirklich. – Omaraf

6

Wenn Sie nicht wollen, ganze Klassen-Datei kopieren, aber für jeden Geschmack Geschmack oder Einstellung zu erkennen und stellen Sie diese dann tun:

In gradle Datei config Feld erstellen:

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

Dann baue Großmeister. Sie können dieses Feld config wie dies in Aktivität zuzugreifen:

@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

Meiner bescheidenen Meinung nach ist das eine viel bessere Antwort. Es ist viel einfacher, all Ihre Menüoptionen zu erstellen und dann diejenigen zu entfernen, die Sie nicht in Ihrem Produktgeschmack benötigen, als verschiedene Versionen von MainActivity zu haben. – SimonH

2

Es gibt eine andere Art und Weise - Wert Datei mit boolean Ressource erstellen, mit unterschiedlichem Wert für jeden Geschmack zB:

Haupt/res/Werte/bool .xml:

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

Teil1 /res/values/bool.xml:

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

und dann in Ihrem Menü reource setzen die Sichtbarkeit Wert abhängig von Ressourcen:

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