Mat*_*ers 13 android android-actionbar
我一直在寻找一种方法来以编程方式更改android中溢出菜单图标的颜色.
我找到的唯一选择是通过添加自定义样式永久更改图标.问题是,在不久的将来,我们需要在使用我们的应用程序时更改此设置.
我们的应用程序是一系列在线平台的扩展,因此用户可以进入其平台的web-url.它们有自己的样式,并将通过API调用来获取应用程序.
这些可能会让我改变图标的颜色......
目前我更改了Actionbar中的其他图标,如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
现在我将不得不使用这些风格.
adn*_*eal 32
您实际上可以使用一个小技巧以编程方式更改溢出图标.这是一个例子:
为溢出菜单创建样式并传入内容描述
<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>
Run Code Online (Sandbox Code Playgroud)
现在请致电ViewGroup.findViewsWithText并传递您的内容说明.所以,像:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// The content description used to locate the overflow button
final String overflowDesc = getString(R.string.accessibility_overflow);
// The top-level window
final ViewGroup decor = (ViewGroup) getWindow().getDecorView();
// Wait a moment to ensure the overflow button can be located
decor.postDelayed(new Runnable() {
@Override
public void run() {
// The List that contains the matching views
final ArrayList<View> outViews = new ArrayList<>();
// Traverse the view-hierarchy and locate the overflow button
decor.findViewsWithText(outViews, overflowDesc,
View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
// Guard against any errors
if (outViews.isEmpty()) {
return;
}
// Do something with the view
final ImageButton overflow = (ImageButton) outViews.get(0);
overflow.setImageResource(R.drawable.ic_action_overflow_round_red);
}
}, 1000);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Add a dummy item to the overflow menu
menu.add("Overflow");
return super.onCreateOptionsMenu(menu);
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果

mic*_*brz 21
Adneal的答案很棒,直到最近才使用它.但后来我想让我的应用程序使用材料设计,从而Theme.AppCompat.*风格和android.support.v7.widget.Toolbar.
是的,它停止了工作,我试图通过设置Your.Theme父母来修复它@style/Widget.AppCompat.ActionButton.Overflow.它通过属性设置工作,contentDescription但在投射时失败了ImageButton.原来在最新的(version 23) android.support.v7课程OverflowMenuButton延伸AppCompatImageView.改变铸造类是为了使其与运行Lollipop的Nexus 5上的工具栏配合使用.
然后我用KitKat在Galaxy S4上运行它,无论我尝试什么,我都无法将溢出设置contentDescription为我的自定义值.但在AppCompat样式中,我发现它已经具有默认值:
<item name="android:contentDescription">@string/abc_action_menu_overflow_description</item>
Run Code Online (Sandbox Code Playgroud)
那么为什么不使用呢?同样由Hannes的想法(在评论中)我实现了监听器,以摆脱一些随机的延迟时间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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当然代替Color.CYAN你可以使用自己的颜色 -activity.getResources().getColor(R.color.black);
编辑:添加了对最新AppCompat库(23)的支持,该库使用AppCompatImageView对于AppCompat 22,您应该将溢出按钮强制转换为TintImageView
Lor*_*rte 19
截至支持23.1工具栏现在有getOverflowIcon()和setOverflowIcon()方法,所以我们可以更容易地做到这一点:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
更改溢出图标的解决方案较少.有一个示例如何更改溢出图标的颜色,但您可以调整它以更改图像:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
有更好的解决方案.您可以在运行时以编程方式执行此操作
toolbar.overflowIcon?.setColorFilter(colorInt, PorterDuff.Mode.SRC_ATOP)
Run Code Online (Sandbox Code Playgroud)
中提琴!
| 归档时间: |
|
| 查看次数: |
32974 次 |
| 最近记录: |