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

Дэвид, я только что нажал на ссылку, и она, кажется, работает для меня.
— 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есть ключ.


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


2
View.bringToFront()это очень тяжелая операция и, как правило, следует избегать любой ценой.
— Доминус

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

0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.