2013-03-10 5 views
11

Ich baue ein Popup-Menü in Android und ich muss einige IDs in jedem Menüpunkt speichern. Die IDs sind String, daher wäre es nett, wenn ich ein Array von String auf das MenuItem setzen könnte.Wie setze ich ein Tag zu MenuItem?

Das Problem ist, dass MenuItem keine setTag-Methode hat.

Wie kann ich sonst noch Daten anhängen?

EDIT: Geobits erwähnt über getActionView();

Leider gibt es null zurück.

Aber ist es sicher, das Folgende zu tun?

View view = new View(getActivity()); 
view.setTag(tag); 
menuItem.setActionView(view); 

Antwort

11

Jeder MenuItem hat ein zugehöriges View eine ActionView genannt. Wenn Sie ein benutzerdefiniertes ActionView verwenden, können Sie es mithilfe von MenuItem.getActionView() abrufen und das Tag darauf setzen/abrufen.

Zum Beispiel um einen Tag gesetzt:

public void setMenuItemTag(MenuItem item, Object tag) 
{ 
    View actionView = item.getActionView(); 
    actionView.setTag(tag); 
} 

bearbeiten

Wenn Sie nicht eine benutzerdefinierte ActionView verwenden, können Sie eine HashMap verwenden Tags zu speichern. Verwenden Sie das MenuItem als Schlüssel.

public void setMenuItemTag(MenuItem item, Object tag) 
{ 
    myMap.put(item, tag); 
} 

// returns null if tag has not been set(or was set to null) 
public Object getMenuItemTag(MenuItem item, Object tag) 
{ 
    return myMap.get(item); 
} 
+4

getActionView null zurück. –

+0

Ah. Nun, in diesem Fall können Sie ein 'HashMap ' einrichten. um sie zu speichern. – Geobits

+0

Ist es besser, eine 'HashMap' zu verwenden oder zu tun, wie ich meinem Beitrag hinzugefügt habe? –

0

Hacky Weg, um Tags zu setzen, wenn keine benutzerdefinierten Ansichten verwenden. Die Idee ist ziemlich einfach, nach der eigentlichen Ansicht erstellt wird, versuchen wir es durch den Text zu finden und Symbol

private void addButtonToMenu(Toolbar toolbar, Menu menu, String title, Drawable icon, String testId) { 
    MenuItem menuItem = menu.add(title); 
    if (icon != null){ 
     menuItem.setIcon(icon); 
    } 
    setTestId(toolbar, title, icon, testId); 
} 

private void setTestId(Toolbar toolbar, String title, Drawable icon, String testId) { 
    UiUtils.runOnPreDrawOnce(toolbar,() -> { 
     ActionMenuView buttonsLayout = ViewUtils.findChildByClass(toolbar, ActionMenuView.class); 
     List<TextView> buttons = ViewUtils.findChildrenByClass(buttonsLayout, TextView.class); 
     for (TextView view : buttons) { 
      if (!TextUtils.isEmpty(title) && title.equals(view.getText())) { 
       view.setTag(testId); 
      } else if (icon != null && ArraryUtils.containes(view.getCompoundDrawables(), icon)) { 
       view.setTag(testId); 
      } 
     } 
    }); 
} 

// Helper functions 

public class UiUtils { 

    public static void runOnPreDrawOnce(final View view, final Runnable task) { 
     view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
      @Override 
      public boolean onPreDraw() { 
       view.getViewTreeObserver().removeOnPreDrawListener(this); 
       task.run(); 
       return true; 
      } 
     }); 
    } 
} 

public class ArrayUtils { 
    public static boolean contains(Object[] array, Object item) { 
     if (isNullOrEmpty(array)) return false; 
     for (Object o : array) { 
      if (o == item) return true; 
     } 
     return false; 
    } 

    private static boolean isNullOrEmpty(Object[] array) { 
     return array == null || array.length == 0; 
    } 
} 

public class ViewUtils { 
    @Nullable 
    public static <T> T findChildByClass(ViewGroup root, Class clazz) { 
     for (int i = 0; i < root.getChildCount(); i++) { 
      View view = root.getChildAt(i); 
      if (clazz.isAssignableFrom(view.getClass())) { 
       return (T) view; 
      } 

      if (view instanceof ViewGroup) { 
       view = findChildByClass((ViewGroup) view, clazz); 
       if (view != null && clazz.isAssignableFrom(view.getClass())) { 
        return (T) view; 
       } 
      } 
     } 
     return null; 
    } 

    public static <T> List<T> findChildrenByClass(ViewGroup root, Class clazz) { 
     List<T> ret = new ArrayList<>(); 
     for (int i = 0; i < root.getChildCount(); i++) { 
      View view = root.getChildAt(i); 
      if (clazz.isAssignableFrom(view.getClass())) { 
       ret.add((T) view); 
      } 
     } 
     return ret; 
    } 
}