Панель инструментов и контекстная панель действий с 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 вышел поверх панели инструментов?

Панель инструментов и контекстная панель действий

ariets
источник
Какую тему использует ваша деятельность?
alanv
Дэвид, я только что нажал на ссылку, и она, кажется, работает для меня.
ariets

Ответы:

320

Обновить:

Решение: используйте свойство windowActionModeOverlay . Установите это в вашей теме:

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

и режим действия будет отображаться над панелью действий вместо нажатия на нее вниз. (Если вы не используете последнюю версию AppCompat, вам нужно добавить к свойству префикс «android:»). Это в основном позволяет AppCompat знать, что у вас есть панель инструментов, расположенная в верхней части экрана, и что он должен рисовать ActionMode поверх нее.


Старый ответ / обходной путь:

Я столкнулся с той же проблемой. Независимо от того, какую тему я установил, она всегда сдвигает панель инструментов, которую я установил как ActionBar. Я пытался с и без поддержки библиотеки, но это не имело значения.

К сожалению, я не смог это исправить, поэтому вместо этого я нашел обходной путь. В моих ActionModeCallback«S 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);

Жаль, что приложение ввода-вывода не использует контекстную панель действий.)

Джейкоб Рас
источник
Да, это было единственное решение, к которому я мог прийти. Однако существуют случаи, когда Contextual ActionBar происходит из системы (например, в WebView или с EditText). Те, для которых вы не получите обратные вызовы. Итак, как бы вы показали / скрыли это за это? (Или я не прав, и вы можете, на самом деле, получить обратные вызовы для CAB с этими)?
Ariets
1
Да, вы можете TextView.setCustomSelectionActionModeCallback () для этого, как описано Александаром в своем ответе.
Джейкоб Рас
1
Ой, уже не могу обновить мой комментарий. Небольшое дополнение: кажется, что setCustomSelectionActionModeCallback нельзя использовать с ActionModeCallback из библиотеки поддержки. Я использую проверку VERSION.SDK_INT для ее установки. По-прежнему необходимо проверить, не возникает ли проблема также на устройствах с предварительной сотовой структурой.
Джейкоб Рас
@ariets, пожалуйста, смотрите мой обновленный ответ. Я чувствую себя немного сбитым с толку за то, что полностью забыл это свойство, но по крайней мере мы можем избавиться от обходного пути сейчас ;-)
Джейкоб Рас
1
Забавно, что я использую последнюю версию (скомпилируйте 'com.android.support:appcompat-v7:22.0.0'), но я должен оставить Android: часть, чтобы он работал ...
Warpzit
16

Не запускайте его на своей деятельности, но на панели инструментов. В вашей деятельности:

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

и вы должны использовать

<item name="windowActionModeOverlay">true</item>
Фрэнк
источник
для меня это делает для android.support.v7.app.ActionBar
Фрэнк
Я получаю эту ошибку-> 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есть ключ.

Jenkyn
источник
8
Вы используете <item name="windowActionModeOverlay">true</item>панель инструментов appcompat, в противном случае вы используете androidпространство имен.
Хавьер Мендонса
бесполезно для меня в моем макете я добавляю панель инструментов, в панели инструментов инициализации действия и setsupport true сделано, пожалуйста, помогите мне
Harsha
<item name = "windowActionModeOverlay"> true </ item> работает должным образом!
Франсуа
8

Решение Джейкоба работало для меня, но контекстный ActionBar был прозрачным, и панель инструментов была видна через него. Это может быть решено следующим образом:

<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()

kunal.c
источник
2
View.bringToFront()это очень тяжелая операция и, как правило, следует избегать любой ценой.
Доминус
Вы правы, но для анимации, например, сверху вниз, экран будет перекрывать панель инструментов. Следовательно, нам нужно использовать toolbar.bringToFront () для анимации под панелью инструментов. Если есть какой-либо альтернативный способ поделиться
:)
0

Еще одно небольшое дополнение: убедитесь, что в активности задано хотя бы пустой экран, setContentView(R.layout.empty_screen)если вы загружаете весь пользовательский интерфейс фрагментами ( ft.replace(android.R.id.content, fragment)).

Андреас Венгер
источник