Adneal 的回答很棒,直到最近我还在使用它。但后来我希望我的应用程序能够使用材料设计,从而使用 Theme.AppCompat.* 样式和 android.support.v7.widget.Toolbar。
是的,它停止工作,我试图通过将 Your.Theme 的父级设置为 @style/Widget.AppCompat.ActionButton.Overflow 来修复它。它通过正确设置contentDescription 工作,但在转换为ImageButton 时失败。结果是最新的(version 23) android.support.v7class OverflowMenuButton 扩展自AppCompatImageView。更改铸造类足以使其与运行 Lollipop 的 Nexus 5 上的工具栏一起使用。
然后我用 KitKat 在 Galaxy S4 上运行它,无论我尝试什么,我都无法将溢出的 contentDescription 设置为我的自定义值。但是在AppCompat styles我发现它已经有默认值了:
<item name="android:contentDescription">@string/abc_action_menu_overflow_description</item>
那么为什么不使用它呢?同样通过 Hannes 的想法(在 cmets 中),我实现了侦听器,以消除postDelayed 中的一些随机延迟时间。由于溢出图标已经在 AppCompat 库中,所以我也会使用它 - 我正在应用颜色过滤器,所以我自己不需要任何图标资源。
我的代码基于 Adneal 对 Android Lollipop 的改进:
public static void setOverflowButtonColor(final Activity activity) {
final String overflowDescription = activity.getString(R.string.abc_action_menu_overflow_description);
final ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final ArrayList<View> outViews = new ArrayList<View>();
decorView.findViewsWithText(outViews, overflowDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) {
return;
}
AppCompatImageView overflow=(AppCompatImageView) outViews.get(0);
overflow.setColorFilter(Color.CYAN);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
根据another StackOverflow answer:
public static void removeOnGlobalLayoutListener(View v, ViewTreeObserver.OnGlobalLayoutListener listener) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
v.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
}
else {
v.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
}
}
当然,您可以使用自己的颜色来代替Color.CYAN - activity.getResources().getColor(R.color.black);
编辑:
添加了对使用 AppCompatImageView 的最新 AppCompat 库 (23) 的支持
对于 AppCompat 22,您应该将溢出按钮投射到 TintImageView