首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更改ActionMode溢出图标

更改ActionMode溢出图标
EN

Stack Overflow用户
提问于 2014-03-29 02:43:21
回答 5查看 6.8K关注 0票数 6

有没有一种方法可以在不改变“普通”ActionBar图标的情况下改变ActionMode溢出图标?

EN

回答 5

Stack Overflow用户

发布于 2014-08-23 00:37:35

我仍然需要弄清楚如何只更改动作模式动作栏内的溢出图标,因为我更改了默认动作栏中看不到的溢出图标(不,我不想更改动作模式动作栏的背景!)

好吧。

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

代码语言:javascript
复制
// 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>

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

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

代码语言:javascript
复制
public void changeOverflowIcon() {
    getTheme().applyStyle(R.style.ChangeOverflowToDark, true);
}

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

代码语言:javascript
复制
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) {}
}

稍微解释一下:

'BaseTheme‘中的赋值是针对ActionBar的。它将选择可绘制的overflow_menu_light,因为我们在您的应用程序的基本主题中指定了它。

代码语言:javascript
复制
getTheme().applyStyle(R.style.ChangeOverflowToDark, true) 

第二个参数true强制当前主题用新属性覆盖旧属性。因为我们只在ChangeOverflowToDark中定义了一个属性,所以它的值被覆盖了。ActionBar不受影响,因为它已经使用了旧属性。但是,操作模式尚未创建(它将在我们从onCreateActionMode(...)返回true时创建)。当操作模式检查此属性值时,它将获得新的属性值。

还有更多...

Manish给出的答案非常棒。我从来没有想过要使用内容描述来找到确切的ImageButton。但是,如果您可以使用简单的findViewById()__找到ImageButton,结果会怎样呢?

以下是您可以执行的操作:

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

代码语言:javascript
复制
<item type="id" name="my_custom_id" />

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

代码语言:javascript
复制
<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>

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

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

代码语言:javascript
复制
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;
    }  
}

两全其美?

假设我们需要将R.drawable.overflow_menu_light用于ActionBar,将R.drawable.overflow_menu_dark用于ActionMode

样式:

代码语言:javascript
复制
<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>

正如我们的风格所定义的那样,ActionBar将选择R.drawable.overflow_menu_dark --但是我们不需要ActionBar的轻量级版本吗?是-我们将在活动的onPrepareOptionsMenu(Menu)回调中分配:

代码语言:javascript
复制
@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);
}

我们之所以在这里这样做,是因为在onPrepareOptionsMenu(Menu)之前,不会创建ImageButton

现在,我们不需要处理ActionMode -因为它将从主题中选取可绘制的dark

我为这个巨大的帖子道歉。我真的希望它能帮上忙。

票数 10
EN

Stack Overflow用户

发布于 2014-08-22 14:21:17

ImageButton是用于显示菜单溢出的小部件。actionOverflowButtonStyle用于设置ImageButton的样式。此样式在ActionMenuPresenter中应用。

代码语言:javascript
复制
private class OverflowMenuButton extends ImageButton implements ActionMenuChildView {
   public OverflowMenuButton(Context context) {
      super(context, null, com.android.internal.R.attr.actionOverflowButtonStyle);
      ...
   }
}

ActionMenuPresenter类用于在action baraction modes中构建操作菜单。因此,通过覆盖主题文件将在两种模式下应用相同的样式。要实现这一点,唯一的方法就是以编程的方式完成,就像在action bar上使用here一样。

这里的代码是如何做到这一点的action mode溢出图标。您可以将drawable分配给ActionMode.Callback.onPrepareActionMode方法中的ImageButton

代码语言:javascript
复制
public class MainActivity extends Activity {
    ViewGroup mDecorView;

    public void onCreate(Bundle savedInstanceState) {
        // Assign mDecorView to later use in action mode callback
        mDecorView = (ViewGroup) getWindow().getDecorView();
    }

    private ActionMode.Callback mCallback = new ActionMode.Callback()
    {
        @Override
        public boolean onPrepareActionMode( ActionMode mode, Menu menu )
        {
            // We have to update the icon after it is displayed, 
            // hence this postDelayed variant. 
            // This is what I don't like, but it is the only way to move forward.

            mDecorView.postDelayed(new Runnable() {

                @Override
                public void run() {
                    ArrayList<View> outViews = new ArrayList<View>();
                    // The content description of overflow button is "More options".
                    // If you want, you can override the style and assign custom content
                    // description and use it here.
                    mDecorView.findViewsWithText(outViews, "More Options", View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION);
                    if(!outViews.isEmpty()) {
                        View v = outViews.get(0);
                        if(v instanceof ImageButton) {
                            ImageButton btn = (ImageButton) v;
                            // Update the image here.
                            btn.setImageResource(R.drawable.custom);
                        }                       
                    }
                }               
            }, 500);

            return true;
        }  

    }
}
票数 3
EN

Stack Overflow用户

发布于 2014-03-29 03:04:50

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

ActionBarSherlock:

代码语言:javascript
复制
<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>

ActioBar:

代码语言:javascript
复制
<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>

确保在清单中设置MyTheme。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22720799

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档