Панель інструментів та контекстний ActionBar з AppCompat-v7


182

Я працюю над використанням нещодавно доданої Панелі інструментів, яка була представлена ​​в Lollipop та бібліотеці AppCompat-v7. Дотримуючись цього керівництва щодо налаштування Панелі інструментів, я помітив, що коли ви викликаєте щось, що відображатиме контекстуальну програму ActionBar (наприклад, виділення тексту для копіювання / вставки), це натисне панель інструментів вниз на сторінку. Ви можете побачити, про що я говорю, на зображенні внизу сторінки:

Отже, по суті, я налаштував це так. У мене в 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);

Хтось знає, як зробити так, щоб контекстний ActionBar надходив поверх панелі інструментів?

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


Яку тему використовує ваша діяльність?
alanv

Девіде, я просто натиснув посилання і, здається, працює для мене.
арієць

Відповіді:


320

Оновлення:

Рішення: використовуйте властивість windowActionModeOverlay . Встановіть це у своїй темі:

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

і режим дії буде показаний на панелі дій, а не натисканням на неї. (Якщо ви не використовуєте останню версію AppCompat, вам потрібно додати у властивість префікс "android:"). Це в основному дозволяє AppCompat знати, що у вас є панель інструментів, розташована у верхній частині екрана, і що вона повинна малювати ActionMode поверх неї.


Стара відповідь / вирішення:

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

На жаль, мені це не вдалося виправити, тому я створив обхідне рішення. У моїх ActionModeCallback«S onCreateActionModeя приховати панель дій:

actionBarToolbar.setVisibility(View.GONE);

і onDestroyActionModeя показую це знову:

actionBarToolbar.setVisibility(View.VISIBLE);

Приховування / показ відбувається так швидко, що це не помітно на моїх тестових пристроях. Звичайно, є і зворотний бік: хоча анімація enter все ще працює, анімація виходу з контекстної панелі дій втрачається, оскільки Панель інструментів негайно спливає на неї. Але поки ми не знайдемо кращого рішення, я думаю, ми стикаємося з цим.


(Моя активність - це фактично розширення спеціального BaseActivityкласу, який має метод, який називається getActionBarToolbar(), взятий із вихідного коду програми Google I / O 2014 , тому я можу легко отримати панель інструментів:

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

Шкода, що додаток вводу-виводу не використовує контекстну панель дій.)


Так, це єдине рішення, до якого я міг також прийти. Однак бувають випадки, коли Contextual ActionBar відбувається з системи (наприклад, в WebView або з EditText). Ті, за які ви не отримуєте зворотних дзвінків. Отже, як би ви хотіли показувати / приховувати це для цього? (Або я помиляюся, і ви, власне, можете отримати зворотній зв'язок для CAB з ними)?
арієць

1
Так, ви можете для цього TextView.setCustomSelectionActionModeCallback () , як описав Олександр у своїй відповіді.
Яків Рас

1
О, я вже не можу оновити коментар. Невелике доповнення: схоже, що setCustomSelectionActionModeCallback не можна використовувати з ActionModeCallback з бібліотеки підтримки. Я використовую перевірку VERSION.SDK_INT, щоб встановити його. Ще потрібно перевірити, чи проблема виникає і на пристроях, що попередньо соти.
Яків Рас

@ariets, будь ласка, дивіться мою оновлену відповідь. Я відчуваю трохи сміття за те, що повністю забув цю власність, але принаймні ми можемо позбутися вирішення проблеми вже зараз ;-)
Jacob Ras

1
Смішно, я використовую останню версію (компілюйте 'com.android.support:appcompat-v7:22.0.0'), але мені доведеться покинути андроїд: частина, щоб він працював ...
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) у View не може бути застосований до (android.support.v7.view.ActionMode.Callback)
Faheem

Ага, гаразд. Моя min версія не менше 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простір імен.
Хав'єр Мендонча

не використовуйте для мене в моєму макеті додаю панель інструментів, у діяльності ініціалізуйте панель інструментів та налаштування підтримки справді зроблено, будь ласка, допоможіть мені
Харша

<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()це дуже важка операція, і її взагалі слід уникати будь-якою ціною.
dominus

Ви праві, але для анімації, наприклад, верхній і нижній частині екрана, буде перекриватися панелі інструментів. Отже, нам потрібно використовувати 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.