在工具栏上显示ActionMode

时间:2014-10-21 09:51:11

标签: android android-support-library android-toolbar android-actionmode

除了传统的android.view.ActionMode之外,我正在尝试将android.support.v7.widget.Toolbar与新android.app.ActionBar一起使用。我可以用以下方式显示它:

toolbar.startActionMode(callback);

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

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

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

10 个答案:

答案 0 :(得分:72)

  

由于您使用的是Toolbar,我还假设您使用的是AppCompatActivity   ActionBar并已将内置的Toolbar替换为   您的自定义setSupportActionBar(toolbar);使用import android.support.v7.view.ActionMode;

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

import android.view.ActionMode;

而不是

_actionMode = startSupportActionMode(this);

然后使用

_actionMode = startActionMode(this);

而不是

{{1}}

答案 1 :(得分:60)

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

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

你必须使用

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

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

答案 2 :(得分:36)

在你的主题中试试这个:

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

答案 3 :(得分:2)

找到您的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>

答案 4 :(得分:2)

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

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

答案 5 :(得分: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();
  }

它对我有用。

答案 6 :(得分: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框架来启用我的应用程序的多个主题,这将改变代码中的主题。当我尝试修改此框架中的样式时,它可以正常工作。

希望它有效。

答案 7 :(得分:1)

因此,经过几天的处理之后,我终于使它工作了。 我想总结一下我所做的。

注意:这是使用Toolbar替换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。

答案 8 :(得分: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));
        }
    }
}

答案 9 :(得分: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:我不得不将代码片段包装在引用块中,否则代码样式似乎不起作用。如果有人可以修复它,请随时编辑。