更改ActionMode溢出图标

TeK*_*eKo 6 android android-actionbar android-actionmode

有没有办法更改ActionMode Overflow图标而不更改"普通"ActionBar的图标?

Vik*_*ram 8

我仍然需要弄清楚如何只更改ActionMode-Actionbar内部的Overflow-Icon,因为我在ActionMode-Actionbar中看不到默认Actionbar中的Overflow-Icon(不,我不想要更改我的ActionMode-Actionbar的背景!)

好的.

让我们从定义一些样式开始.我将尝试解释为什么我们以这种方式定义它们:

// This is just your base theme. It will probably include a lot more stuff.
// We are going to define the style 'OverflowActionBar' next.

<style name="BaseTheme" parent="android:Theme.Holo.Light">
    ....
    ....
    ....
    <item name="android:actionOverflowButtonStyle">@style/OverflowActionBar</item>
</style>

// Assigning a parent to this style is important - we will inherit two attributes -
// the background (state-selector) and the content description

<style name="OverflowActionBar" parent="@android:style/Widget.Holo.ActionButton.Overflow">
    <item name="android:src">@drawable/overflow_menu_light</item>
</style>

// Next up is an extension to our 'BaseTheme'. Notice the parent here.

<style name="ChangeOverflowToDark" parent="@style/BaseTheme">
    <item name="android:actionOverflowButtonStyle">@style/OverflowActionMode</item>
</style>

// One last thing is to define 'OverflowActionMode'. Again, we inherit useful
// attributes by assigning 'Widget.Holo.ActionButton.Overflow' as the parent.

<style name="OverflowActionMode" parent="@android:style/Widget.Holo.ActionButton.Overflow">
    <item name="android:src">@drawable/overflow_menu_dark</item>
</style>
Run Code Online (Sandbox Code Playgroud)

我们所有的工作styles.xml都已完成.最后一点发生在运行时.我想你已经实现了ActionMode.Callback.

在您的活动中,定义一个方法 - changeOverflowIcon():

public void changeOverflowIcon() {
    getTheme().applyStyle(R.style.ChangeOverflowToDark, true);
}
Run Code Online (Sandbox Code Playgroud)

您将从onCreateActionMode(...)您的ActionMode.Callback实现中调用此方法:

public class CustomActionModeCallback implements ActionMode.Callback {

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        changeOverflowIcon()

        // other initialization

        return true;
    }

    @Override
    public boolean onPrepareActionMode(final ActionMode mode, Menu menu) {
        return true;
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        return false;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {}
}
Run Code Online (Sandbox Code Playgroud)

一点解释:

'BaseTheme'中的作业是为了ActionBar.它将选择drawable,overflow_menu_light因为我们在您的应用程序的基本主题中分配它.

getTheme().applyStyle(R.style.ChangeOverflowToDark, true) 
Run Code Online (Sandbox Code Playgroud)

第二个参数true强制当前主题使用新属性覆盖旧属性.由于我们只定义了一个属性ChangeOverflowToDark,因此会覆盖其值.将ActionBar不会受到影响,因为它已经使用了旧的属性.但是,动作模式尚未形成的(当我们返回它会创建trueonCreateActionMode(...)).当操作模式检查此属性值时,它将获取新属性值.

还有更多...

Manish给出的答案非常棒.我从来没有想过使用内容描述来找到确切的ImageButton.但是,如果你能找到ImageButton直截了当的用途findViewById()怎么办?

以下是您的方法:

首先,我们需要独特的ID.如果您的项目当前没有res/values/ids.xml文件,请创建一个.添加新ID:

<item type="id" name="my_custom_id" />
Run Code Online (Sandbox Code Playgroud)

我上面讨论的设置将保持不变.唯一的区别在于OverflowActionMode风格:

<style name="OverflowActionMode" parent="@android:style/Widget.Holo.ActionButton.Overflow">
    <item name="android:src">@drawable/overflow_menu_dark</item>
    <item name="android:id">@id/my_custom_id</item>
</style>
Run Code Online (Sandbox Code Playgroud)

我们上面定义的id将被分配给ImageButton我们调用的时间getTheme().applyStyle(R.style.ChangeOverflowToDark, true);

我将从Manish的答案中借用代码片段:

private ActionMode.Callback mCallback = new ActionMode.Callback()
{
    @Override
    public boolean onPrepareActionMode( ActionMode mode, Menu menu )
    {

        mDecorView.postDelayed(new Runnable() {

            @Override
            public void run() {
                ImageButton btn = (ImageButton) mDecorView.findViewById(R.id.my_custom_id);
                // Update the image here.
                btn.setImageResource(R.drawable.custom);
            }          
        }, 500); // 500 ms is quite generous // I would say that 50 will work just fine

        return true;
    }  
}
Run Code Online (Sandbox Code Playgroud)

两全其美?

比方说,我们需要R.drawable.overflow_menu_lightActionBarR.drawable.overflow_menu_darkActionMode.

样式:

<style name="BaseTheme" parent="android:Theme.Holo.Light">
    ....
    ....
    ....
    <item name="android:actionOverflowButtonStyle">@style/OverflowActionMode</item>
</style>

<style name="OverflowActionMode" parent="@android:style/Widget.Holo.ActionButton.Overflow">
    <item name="android:src">@drawable/overflow_menu_dark</item>
    <item name="android:id">@id/my_custom_id</item>
</style>
Run Code Online (Sandbox Code Playgroud)

根据我们的风格定义,ActionBar将选择R.drawable.overflow_menu_dark- 但我们不需要轻型版本ActionBar?是的 - 我们将在活动的onPrepareOptionsMenu(Menu)回调中分配:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            ImageButton ib = (ImageButton) 
                                 getWindow().getDecorView()
                                .findViewById(R.id.my_custom_id);
            if (ib != null)
                ib.setImageResource(R.drawable.overflow_menu_light);
        }
    }, 50L);
    return super.onPrepareOptionsMenu(menu);
}
Run Code Online (Sandbox Code Playgroud)

因为在此之前我们在这里做这个onPrepareOptionsMenu(Menu)时,ImageButton就不会被创建.

现在,我们并不需要处理ActionMode-因为它会选择dark从主题绘制.

我为这个巨大的帖子道歉.我真的希望它有所帮助.

  • 这只是一个惊人的解释!你的第一个教程非常好!在我看来,这是一个比处理Handlers和Runnables更美丽的方式....谢谢你!:)) (2认同)

Mar*_* S. 1

您应该能够使用样式来做到这一点:

动作栏夏洛克:

<style name="MyTheme" parent="Theme.Sherlock.Light">
    <item name="actionOverflowButtonStyle">@style/MyTheme.OverFlow</item>
</style>

<style name="MyTheme.OverFlow" parent="Widget.Sherlock.ActionButton.Overflow">
    <item name="android:src">@drawable/YOUR_ICON_GOES_HERE</item>
</style>
Run Code Online (Sandbox Code Playgroud)

动作栏:

<style name="MyTheme" parent="@android:style/Theme.Holo">
    <item name="android:actionOverflowButtonStyle">@style/MyTheme.OverFlow</item>
</style>

<style name="MyTheme.OverFlow" parent="@android:style/Widget.Holo.ActionButton.Overflow">
    <item name="android:src">@drawable/YOUR_ICON_GOES_HERE</item>
</style>
Run Code Online (Sandbox Code Playgroud)

确保在清单中设置 MyTheme。