带有AppCompat-v7的工具栏和上下文操作栏


182

我正在使用Lollipop和AppCompat-v7库中引入的新添加的工具栏。我按照本指南设置工具栏时,发现,当您调用将弹出上下文操作栏的内容(例如突出显示要复制/粘贴的文本)时,它将在页面上向下推工具栏。您可以在页面底部的图像中看到我在说什么:

因此,基本上,我是这样设置的。我在与包含标签一起使用的xml文件中定义了工具栏:

<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorPrimary"/>

然后,我将其实例化为:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/root"
    tools:context=".MainActivity">

    <include
        layout="@layout/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/> 

    <!-- Rest of view -->

    </LinearLayout>

在代码中,我将其设置如下:

    // On Create method of activity:
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

有谁知道如何使Contextual ActionBar出现在工具栏的上方?

工具栏和上下文操作栏


您的活动使用什么主题?
alanv 2014年

大卫,我只是单击了链接,它似乎对我有用。
ariets

Answers:


319

更新:

解决方案:使用windowActionModeOverlay属性。在您的主题中进行设置:

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

动作模式将显示在动作栏上,而不是向下推。(如果您没有使用最新的AppCompat,则需要在属性中添加“ android:”前缀)。基本上,它使AppCompat知道您在屏幕顶部有一个工具栏,并且应该在屏幕上方绘制ActionMode。


旧答案/解决方法:

我遇到了同样的问题。无论我设置了什么主题,它总是会向下推我设置为ActionBar的工具栏。我尝试有无支持库,但这没关系。

不幸的是我无法修复它,所以我建立了一个解决方法。在我ActionModeCallback的中,onCreateActionMode我隐藏了操作栏:

actionBarToolbar.setVisibility(View.GONE);

然后onDestroyActionMode再次显示:

actionBarToolbar.setVisibility(View.VISIBLE);

隐藏/显示的速度如此之快,在我的测试设备上并不明显。当然有一个缺点:尽管输入动画仍然有效,但是上下文操作栏的退出动画会丢失,因为工具栏会立即弹出该动画。但是,除非我们找到更好的解决方案,否则我想我们会一直坚持下去。


(“我的活动”实际上是在扩展自定义BaseActivity类,该类具有一个称为的方法getActionBarToolbar(),该方法取自Google I / O 2014应用程序源代码,因此我可以轻松获取工具栏:

BaseActivity activity = (BaseActivity) getActivity();
activity.getActionBarToolbar().setVisibility(View.GONE);

太糟糕了,I / O应用程序未使用上下文操作栏。)


是的,这也是我唯一能想到的解决方案。但是,在某些情况下,上下文ActionBar会从系统发生(例如,在WebView中或带有EditText)。那些您没有获得回调的对象。那么,您将如何显示/隐藏它呢?(或者我做错了,实际上,您可以使用这些回调获得CAB的回调)?
ariets 2014年

1
是的,您可以为此设置TextView.setCustomSelectionActionModeCallback(),就像Aleksandar在其答案中所述。
雅各布拉斯2014年

1
哦,已经无法更新我的评论了。小增加:似乎setCustomSelectionActionModeCallback不能与支持库中的ActionModeCallback一起使用。我正在使用VERSION.SDK_INT检查进行设置。仍然需要测试在蜂窝前设备上是否也出现此问题。
雅各布拉斯2014年

@ariets,请参阅我的最新答案。对于完全忘记该财产,我感到有些沮丧,但是至少我们现在可以摆脱解决方法;-)
Jacob Ras 2014年

1
有趣的是,我使用的是最新版本(编译为com.android.support:appcompat-v7:22.0.0'),但我必须省去android系统的工作……
Warpzit 2015年

16

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

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

而你必须使用

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

对我来说,它适用于android.support.v7.app.ActionBar
Frank

我收到此错误->视图中的startActionMode(android.view.ActionMode.Callback)无法应用于(android.support.v7.view.ActionMode.Callback)
Faheem

啊好吧。我的最小版本不小于11。因此,我可以使用android.view.ActionMode。在android.support.v7.widget.Toolbar上进行回调,我从未使用过android.support.v7.view.ActionMode.Callback。
弗兰克,

值得一提的是AppCompatActivity.startSupportActionMode(callback),要与app:iconTint菜单项xmls中的属性兼容。
geekley

14

只是一小部分:对于

<item name="windowActionModeOverlay">true</item>
要工作,重要的是在活动super.onCreate(savedInstanceState) 之前致电setContentView(R.layout.your_activity)。在这种情况下确实有所不同!


11

就我而言, <item name="windowActionModeOverlay">true</item>没有用,但是这项工作:<item name="android:windowActionModeOverlay">true</item>,这android是关键。


8
您使用<item name="windowActionModeOverlay">true</item>appcompat工具栏,否则使用android名称空间。
哈维尔·门登萨(JavierMendonça),2015年

在我的布局中对我无用的是添加工具栏,在活动中初始化工具栏并setsupport true完成,请帮助我
Harsha

<item name =“ windowActionModeOverlay”> true </ item>正常工作!
弗朗索瓦·

8

Jacob的解决方案对我有用,但上下文的ActionBar是透明的,而Toolbar通过它可见。可以解决以下问题:

<style name="AppTheme.Base" parent="Theme.AppCompat.Light">
    ....
    ....
    <item name="actionModeStyle">@style/CustomActionMode</item>
</style>

<style name="CustomActionMode" parent="@style/Widget.AppCompat.ActionMode">
    <item name="background">@color/primary_material_light</item>
</style>

主题“ AppTheme.Base”必须是应用于工具栏的主题。

有关上下文ActionBar样式的更多详细信息:

如何在材料设计中使用appCompat自定义上下文操作栏


0

将工具栏置于最前面的非常有用的方法 toolbar.bringToFront()


2
View.bringToFront()操作非常繁重,通常应不惜一切代价避免。
dominus 2015年

是的,但是对于动画(例如,屏幕顶部到底部)将与工具栏重叠。因此,我们需要使用toolbar.bringToFront()以下toolbar.If生命的存在,你可以分享任何另一种方法:)
kunal.c

0

另一个小的补充:setContentView(R.layout.empty_screen)如果您将整个ui加载到片段(ft.replace(android.R.id.content, fragment))中,请确保在活动中至少设置一个空白屏幕。

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.