为了账号安全,请及时绑定邮箱和手机立即绑定

以编程方式更改Android Overflow菜单图标

/ 猿问

以编程方式更改Android Overflow菜单图标

慕码人8056858 2019-12-13 17:10:28

我一直在寻找一种方法来以编程方式更改android中溢出菜单图标的颜色。


我发现的唯一选择是通过添加自定义样式来永久更改图标。问题在于,在不久的将来,我们将需要在使用应用程序时更改此设置。


我们的应用是一系列在线平台的扩展,因此用户可以输入其平台的网络网址。这些都有自己的样式,将通过对应用程序的API调用获取。


这些可能会使我改变图标的颜色...


目前,我在操作栏中更改了其他图标,如下所示:


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);

}

现在,我将不得不使用样式。


查看完整描述

3 回答

?
弑天下

实际上,您可以使用一些技巧以编程方式更改溢出图标。这是一个例子:


为溢出菜单创建样式并传递内容描述


<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>

现在调用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);

}

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);

        }

    }

}



查看完整回答
反对 回复 2019-12-14
?
翻过高山走不出你

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>

那么为什么不使用它呢?同样,根据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);

        }

    });

}

并根据另一个StackOverflow答案:


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);


编辑:添加了对最新AppCompat库(23)的支持,该库使用AppCompatImageView对于AppCompat 22,应将溢出按钮投射到TintImageView



查看完整回答
反对 回复 2019-12-14
?
犯罪嫌疑人X

有一种用于更改溢出图标的简单易用的解决方案。有一个示例如何更改溢出图标的颜色,但是您可以对其进行调整以更改图像:


 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);

        }

    }



查看完整回答
反对 回复 2019-12-14

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信