不使用自定义视图时设置标签的黑客方法。这个想法很简单,创建实际视图后,我们尝试通过它的文本和图标找到它
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;
}
}