92

除了传统的,我正在尝试使用android.view.ActionMode新的。我可以通过以下方式显示它:android.support.v7.widget.Toolbarandroid.app.ActionBar

toolbar.startActionMode(callback);

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

我试图在我的主题中设置以下内容,但它似乎没有改变任何东西:

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

10 回答 10

86

由于您使用的是Toolbar,我还假设您使用的是 并且已经用 您的自定义AppCompatActivity替换了内置ActionBarToolbarsetSupportActionBar(toolbar);

首先确保您正在导入正确的命名空间:

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

并不是

import android.view.ActionMode;

然后使用

_actionMode = startSupportActionMode(this);

并不是

_actionMode = startActionMode(this);
于 2015-05-04T14:04:14.860 回答
70

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

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

你必须使用

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

正如安德烈所说,在你的主题中。

于 2014-12-08T09:13:51.510 回答
46

在你的主题中试试这个:

<item name="windowActionModeOverlay">true</item>
于 2014-10-26T19:21:30.133 回答
16

我认为人们没有说清楚的一件事是这条线

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

于 2019-02-24T15:31:01.813 回答
7

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

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

就像:

<style name="WorkTimeListTheme" parent="AppTheme.NoActionBar">
        <item name="windowActionModeOverlay">true</item>
        <item name="actionModeBackground">@color/theme_primary</item>
    </style>
于 2018-12-21T06:51:31.740 回答
5

所以,经过几天的努力,我终于让它工作了。我想总结一下我做了什么。

注意:这是使用 aToolbar替换ActionBar.AppCompatActivity

  1. 我将这一行添加到我的AppTheme:它告诉 android 您希望您的操作模式覆盖工具栏
<item name="windowActionModeOverlay">true</item>
  1. 使用正确的导入:

您必须使用这些导入才能使用AppCompatActivity

import androidx.appcompat.view.ActionMode;
// or
import android.support.v7.view.ActionMode;
  1. 在您的 Activity 上启动 ActionMode,如下所示:
actionMode = startSupportActionMode(callback);

而不是这样:

actionMode = startActionMode(callback);

您的 Activity 会自动在工具栏上创建 ActionMode,因为它被设置为 supportActionToolbar。该样式将 dsiplaying 处理为叠加。

感谢@Kuffs 和@Lefty。

于 2020-09-23T21:53:37.580 回答
2

这是我提出的解决方案。

在我的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();
  }

这个对我有用。

于 2015-06-05T09:14:05.193 回答
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 方法。同时我也尝试修改给定活动的主题。当然,它不起作用。所以,如果你真的没有更好的选择,你可以试试这个。

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

希望它有效。

于 2018-01-03T11:46:35.043 回答
0

您可以留下所有仅适用于某些场景/手机/蓝月亮的垃圾,然后简单地破解它(以非常干净的方式):

  1. 创建 2 菜单Groups
<menu>
  <group android:id="@+id/group_normal">
      <item id="@+id/action_edit"/>
  </group>
  <group android:id="@+id/group_action_mode"
      android:visible="false">
      <item id="@+id/action_mode_1"/>
      <item id="@+id/action_mode_2"/>
      ..
  </group>
</menu>
  1. 在您的Fragment(或Activity)中:
class MyFragment: Fragment() {

  private var actionMode = false

    override fun onCreateView(
      inflater: LayoutInflater, container: ViewGroup?,
      savedInstanceState: Bundle?
  ): View? {
        toolbar.apply {
          setNavigationOnClickListener {
              if(actionMode) endActionMode(this)
              else findNavController().navigateUp()
          }
          setOnMenuItemClickListener {
              when(it.itemId) {
                  R.id.action_edit -> {
                      // start action mode
                      startActionMode(this)
                  }
                  R.id.action_mode_1 -> {
                      // todo
                  }
                  R.id.action_mode_2 -> {
                      // todo
                      endActionMode(this)
                  }
                  ...
                  else -> return@setOnMenuItemClickListener false
              }
              true
          }
      }
    }

  private fun startActionMode(toolbar: Toolbar) {
      with(toolbar.menu) {
          setGroupVisible(R.id.group_normal, false)
          setGroupVisible(R.id.group_action_mode, true)
      }
      toolbar.title = 0 // todo format number of selected items
      actionMode = true
  }

  private fun endActionMode(toolbar: Toolbar) {
      with(toolbar.menu) {
          setGroupVisible(R.id.group_normal, true)
          setGroupVisible(R.id.group_action_mode, false)
      }
      toolbar.setTitle(R.string.original_title)
      actionMode = false
  }
}

每次都按预期工作。根据需要添加额外的功能。

PS:我不得不将代码片段包装在引号块中,否则代码样式似乎不起作用。如果有人可以修复它,请随时编辑。

于 2021-01-14T15:07:04.600 回答
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));
        }
    }
}
于 2020-03-02T00:36:46.860 回答