在工具栏上显示ActionMode


87

除了传统的,我正在尝试将android.view.ActionMode搭配新android.support.v7.widget.Toolbarandroid.app.ActionBar。我可以显示它:

toolbar.startActionMode(callback);

问题是ActionMode会在上方显示ActionBar,而不是在上方显示Toolbar。有办法改变吗?

我尝试在主题中设置以下内容,但似乎没有任何改变:

<item name="windowActionModeOverlay">true</item>

1
我认为ActionMode是ActionBar的一部分,您无法更改其位置
SpyZip 2014年

这太糟糕了。感谢您的回答
盖坦

1
您是否已将工具栏设置为操作栏?
Nikola Despotoski 2014年

1
仍然有同样的问题,对此有任何更新吗?我遇到了同样的情况,一个工具栏作为经典操作栏,下面一个工具栏,作为标题和选项菜单,如下所示。面临此问题,并且无法将actionmode下移。
cV2

Answers:


82

由于您使用的是Toolbar,我还以为你正在使用的 AppCompatActivity和已经取代了内置的ActionBar与您的自定义Toolbar使用 setSupportActionBar(toolbar);

首先,请确保您导入正确的名称空间:

import androidx.appcompat.view.ActionMode;
// Or
import android.support.v7.view.ActionMode;

并不是

import android.view.ActionMode;

然后使用

_actionMode = startSupportActionMode(this);

并不是

_actionMode = startActionMode(this);

35
这加上windowActionModeOverlay设置对我有用。
Jimeux 2015年

4
我目前正在使用AppCompatActivity,添加windowActionModeOverlay 对我来说已经足够。我尝试使用import,android.support.v7.view.ActionMode但它不适用于MultiChoiceModeListener,因此最终使用了import android.view.ActionMode。您知道是否有的支持版本MultiChoiceModeListener吗?谢谢
Axel

有MultiChoiceModeListener的支持版本吗?
galaxigirl

@galaxigirl,似乎没有。您必须处理适配器中的单击事件并查看持有人
peterchaula

67

不要在您的活动上启动它,而是在工具栏上启动它。在您的活动中:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.startActionMode(mActionModeCallback)

而你必须使用

<item name="windowActionModeOverlay">true</item>

就像安德烈(Andre)所说的那样。


1
这对我有用,因为我也有特殊要求。ActionMode.Callback我不想实施,而是想实施MultiChoiceModeListener。使用支持的问题ActionMode在于似乎没有的支持版本MultiChoiceModeListener
jwir3

43

在您的主题中尝试以下操作:

<item name="windowActionModeOverlay">true</item>

如我的问题所述,我已经尝试过了,但没有成功。但是谢谢你!
加坦2014年

抱歉,我没有意识到您已经尝试过了。您确定它不起作用吗?这个对我有用。
安德烈·雷斯蒂沃

我有同样的问题,并且可以解决。谢谢!
玛塔·罗德里格斯

2
我尝试使用android:前缀和不使用前缀,然后将其放在应用程序主题中。该ActionMode覆盖的ActionBar,但我想它在我Toolbar,这是下面的ActionBar
加坦2014年

@Gaëtan你得到答案了吗?我遇到了同样的问题,由于我的应用程序支持API 21及更高版本,因此我扩展了Activity而不是AppCompatActivity。
SjDev

14

我认为人们不清楚的一件事是

<item name="windowActionModeOverlay">true</item>

放置在基本主题中,即AppTheme而不是AppTheme.NoActionBar

<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionModeOverlay">true</item>
</style>

<style name="transparent" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
</style>


<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />


这是我唯一需要的更改。谢谢!
PNDA

5

找到您的AndroidManifest.xml,然后在您的应用程序或Activity主题中添加以下代码

<item name="windowActionModeOverlay">true</item>

像这样:

<style name="WorkTimeListTheme" parent="AppTheme.NoActionBar">
        <item name="windowActionModeOverlay">true</item>
        <item name="actionModeBackground">@color/theme_primary</item>
    </style>

1

这是我提出的解决方案。

在我的ActionMode.Callback的onCreateActionMode方法中,添加以下内容:

StandaloneActionMode standaloneActionMode = (StandaloneActionMode) actionMode;
Field mContextView;
try {
     mContextView = StandaloneActionMode.class.getDeclaredField("mContextView");
     mContextView.setAccessible(true);
     View contextView = (View) mContextView.get(standaloneActionMode);
     MarginLayoutParams params = (MarginLayoutParams) contextView.getLayoutParams();
     params.topMargin = mToolbar.getTop();
  } catch (NoSuchFieldException e) {
            e.printStackTrace();
  } catch (IllegalAccessException e) {
            e.printStackTrace();
  } catch (IllegalArgumentException e) {
            e.printStackTrace();
  }

这个对我有用。


1

我已经尝试了上述所有方法,但是仍然无法正常工作。然后,我尝试了以下方法:

    private class ActionModeCallback implements ActionMode.Callback {
    @Override
    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
        actionMode.getMenuInflater().inflate(R.menu.note_find_action, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
        ((AppCompatActivity) getActivity()).getSupportActionBar().hide();
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
        return false;
    }

    @Override
    public void onDestroyActionMode(ActionMode actionMode) {
        ((AppCompatActivity) getActivity()).getSupportActionBar().show();
    }
}

在这里,我使用了支持库的动作模式和startSupportActionMode方法。同时,我也尝试修改给定活动的主题。当然,它不起作用。因此,如果您真的没有更好的选择,可以尝试这一方法。

就在最近,我发现我使用了Colorful框架启用了我的应用程序的多个主题,这将更改代码中的主题。当我尝试在此框架中修改样式时,它可以工作。

希望它能工作。


这是唯一对我有用的东西。非常感谢。
拉奇

0

如果您看到视图树,则可以编写以下代码:

 ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
    traverseView(decorView);
 /**
 * traverse find actionmodebar
 * @param root  view
 */
public void traverseView(View root) {
    if (root==null){
        return;
    }
    if (root instanceof ActionBarContextView){
        root.setVisibility(View.GONE);
        return;
    }
    if ((root instanceof ViewGroup)) { // If view is ViewGroup, apply this method on it's child views
        ViewGroup viewGroup = (ViewGroup) root;
        for (int i = 0; i < viewGroup.getChildCount(); ++i) {
            traverseView(viewGroup.getChildAt(i));
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.