以编程方式更改Android溢出菜单图标
我一直在寻找一种方法,以编程方式更改android中溢出菜单图标的颜色 我找到的唯一选择是通过添加自定义样式永久更改图标。 问题是,在不久的将来,我们需要在使用我们的应用程序时改变这一点 我们的应用程序是一系列在线平台的扩展,因此用户可以输入其平台的web url。它们有自己的风格,将通过对应用程序的API调用获取 这些可能要求我更改图标的颜色 目前,我更改了Actionbar中的其他图标,如下所示:以编程方式更改Android溢出菜单图标,android,android-actionbar,Android,Android Actionbar,我一直在寻找一种方法,以编程方式更改android中溢出菜单图标的颜色 我找到的唯一选择是通过添加自定义样式永久更改图标。 问题是,在不久的将来,我们需要在使用我们的应用程序时改变这一点 我们的应用程序是一系列在线平台的扩展,因此用户可以输入其平台的web url。它们有自己的风格,将通过对应用程序的API调用获取 这些可能要求我更改图标的颜色 目前,我更改了Actionbar中的其他图标,如下所示: if (ib != null){ Drawable resIcon =
if (ib != null){
Drawable resIcon = getResources().getDrawable(R.drawable.navigation_refresh);
resIcon.mutate().setColorFilter(StyleClass.getColor("color_navigation_icon_overlay"), PorterDuff.Mode.SRC_ATOP);
ib.setIcon(resIcon);
}
现在我必须使用样式。实际上,您可以使用一个小技巧以编程方式更改溢出图标。下面是一个例子: 为溢出菜单创建样式并传入内容描述
<style name="Widget.ActionButton.Overflow" parent="@android:style/Widget.Holo.ActionButton.Overflow">
<item name="android:contentDescription">@string/accessibility_overflow</item>
</style>
<style name="Your.Theme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
<item name="android:actionOverflowButtonStyle">@style/Widget.ActionButton.Overflow</item>
</style>
View.findViewsWithText
是在API级别14中添加的,因此您必须使用自己的兼容方法:
static void findViewsWithText(List<View> outViews, ViewGroup parent, String targetDescription) {
if (parent == null || TextUtils.isEmpty(targetDescription)) {
return;
}
final int count = parent.getChildCount();
for (int i = 0; i < count; i++) {
final View child = parent.getChildAt(i);
final CharSequence desc = child.getContentDescription();
if (!TextUtils.isEmpty(desc) && targetDescription.equals(desc.toString())) {
outViews.add(child);
} else if (child instanceof ViewGroup && child.getVisibility() == View.VISIBLE) {
findViewsWithText(outViews, (ViewGroup) child, targetDescription);
}
}
}
static void findViewWithText(列表视图、视图组父视图、字符串targetDescription){
if(parent==null | | TextUtils.isEmpty(targetDescription)){
返回;
}
final int count=parent.getChildCount();
for(int i=0;i
结果
阿德尼尔的答案很好,我一直在使用它,直到最近。但后来我想让我的应用程序利用材料设计,从而
Theme.AppCompat.*
style和android.support.v7.widget.Toolbar
是的,它停止工作了,我试图通过将.Theme的父项设置为@style/Widget.AppCompat.ActionButton.Overflow来修复它。它通过属性设置contentDescription
工作,但在转换到ImageButton
时失败。在最新的android.support.v7版本中,是从AppCompatImageView
扩展而来的。改变铸造类足以使它与运行棒棒糖的Nexus5工具栏一起工作
然后我用KitKat在Galaxy S4上运行了它,无论我做了什么尝试,我都无法将overflow的contentDescription
设置为我的自定义值。但在中,我发现它已经具有默认值:
<item name="android:contentDescription">@string/abc_action_menu_overflow_description</item>
并根据:
public static void removeOnGlobalLayoutListener(视图v,ViewTreeObserver.OnGlobalLayoutListener){
if(Build.VERSION.SDK\u INT
当然,您可以使用自己的颜色,而不是Color.CYAN
activity.getResources().getColor(R.Color.black)代码>
编辑:
添加了对最新AppCompat库(23)的支持,该库使用AppCompatImageView
对于AppCompat 22,您应该将溢出按钮强制转换为TintImageView基于@michalbrz answer,我使用下面的更改图标本身:
public静态无效setOverflowButtonColor(最终活动){
最终字符串溢出描述=activity.getString(R.String.abc\u action\u menu\u overflow\u description);
最终视图组decorView=(视图组)activity.getWindow().getDecorView();
final ViewTreeObserver ViewTreeObserver=decorView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(新viewTreeObserver.OnGlobalLayoutListener(){
@凌驾
公共图书馆{
最终ArrayList OutView=新ArrayList();
decorView.FindView WithText(OutView、overflowDescription、,
查看。查找带有内容描述的视图);
if(outview.isEmpty()){
返回;
}
TintImageView溢出=(TintImageView)outViews.get(0);
//overflow.setColorFilter(Color.CYAN);//更改颜色
溢出.setImageResource(R.drawable.dots);
移除LobalLayoutListener(decorView,本);
}
});
使用appcompat-v7:23.0.1没有一个@adneal或@michalbrz对我有效。我必须更改@michalbrz答案的两行代码才能使其生效。
我添加了一个答案,因为当前的两个答案对某人都很有用,但是如果您使用的是像我一样的最新appcompat版本,那么您应该使用基于@michalbrz:
private static void setOverflowButtonColor(final AppCompatActivity activity, final PorterDuffColorFilter colorFilter) {
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<>();
decorView.findViewsWithText(outViews, overflowDescription,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
if (outViews.isEmpty()) {
return;
}
ActionMenuItemView overflow = (ActionMenuItemView)outViews.get(0);
overflow.getCompoundDrawables()[0].setColorFilter(colorFilter);
removeOnGlobalLayoutListener(decorView,this);
}
});
}
因此,在ActionMenuItemView
的代码中挖掘了一点之后,我发现了如何获得图标的可绘制性(查看setIcon()
),然后我将强制转换更改为ActionMenuItemView
,对从getCompoundDrawables()获得的左侧可绘制性应用颜色过滤器
瞧!它工作了!从支持23.1开始,工具栏现在有了新的工具和方法,因此我们可以更轻松地完成这项工作:
public static void setOverflowButtonColor(final Toolbar toolbar, final int color) {
Drawable drawable = toolbar.getOverflowIcon();
if(drawable != null) {
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable.mutate(), color);
toolbar.setOverflowIcon(drawable);
}
}
对于更改溢出图标,有一种不太老套的解决方案。下面是一个如何更改溢出图标颜色的示例,但您可以调整它以更改图像:
private void setOverflowIconColor(int color) {
Drawable overflowIcon = toolbar.getOverflowIcon();
if (overflowIcon != null) {
Drawable newIcon = overflowIcon.mutate();
newIcon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
toolbar.setOverflowIcon(newIcon);
}
}
伙计们,我用一种简单的方式完成了这项工作,请看下面的片段:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_dashboard, menu);
MenuItem item = menu.findItem(R.id.help);
Drawable drawable = item.getIcon();
drawable.setColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP);
return super.onCreateOptionsMenu(menu);
}
如果这里有更多的澄清,请告诉我。有更好的解决方案。您可以在运行时以编程方式进行
toolbar.overflowIcon?.setColorFilter(colorInt, PorterDuff.Mode.SRC_ATOP)
Viola!不需要创建新的样式资源,只需使用setOvewflowIcon(drawable)方法到工具栏对象,并将要用作图标的drawable传递给它
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setOverflowIcon(getResources().getDrawable(R.drawable.ic_notifications_black_24dp));
toolBar.overflowIcon?.setTint(Color.WHITE)
在科特林,
更改您想要的任何颜色:)
public static void setOverflowButtonColor(final Toolbar toolbar, final int color) {
Drawable drawable = toolbar.getOverflowIcon();
if(drawable != null) {
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(drawable.mutate(), color);
toolbar.setOverflowIcon(drawable);
}
}
private void setOverflowIconColor(int color) {
Drawable overflowIcon = toolbar.getOverflowIcon();
if (overflowIcon != null) {
Drawable newIcon = overflowIcon.mutate();
newIcon.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
toolbar.setOverflowIcon(newIcon);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_dashboard, menu);
MenuItem item = menu.findItem(R.id.help);
Drawable drawable = item.getIcon();
drawable.setColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP);
return super.onCreateOptionsMenu(menu);
}
toolbar.overflowIcon?.setColorFilter(colorInt, PorterDuff.Mode.SRC_ATOP)
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setOverflowIcon(getResources().getDrawable(R.drawable.ic_notifications_black_24dp));