Toolbar dan ActionBar Kontekstual dengan AppCompat-v7

182

Saya sedang berupaya menggunakan Toolbar yang baru ditambahkan yang diperkenalkan di Lollipop dan perpustakaan AppCompat-v7. Saya mengikuti panduan ini tentang pengaturan Toolbar. Saya perhatikan ketika Anda memanggil sesuatu yang akan memunculkan ActionBar kontekstual (seperti menyorot teks untuk disalin / ditempelkan), itu akan mendorong Toolbar ke bawah pada halaman. Anda dapat melihat apa yang saya bicarakan dalam gambar di bagian bawah halaman:

Jadi, pada dasarnya, saya mengaturnya seperti ini. Saya memiliki Toolbar yang didefinisikan dalam file xml yang saya gunakan dengan menyertakan tag:

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

Lalu, saya instantiate dalam pandangan saya:

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

Dalam kode, saya mengaturnya seperti ini:

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

Adakah yang tahu cara membuatnya sehingga ActionBar Kontekstual muncul di atas Toolbar?

Bilah Alat dan ActionBar Kontekstual

ariets
sumber
Apa tema yang digunakan aktivitas Anda?
alanv
David, saya baru saja mengklik tautannya dan sepertinya itu berfungsi untuk saya.
ariets

Jawaban:

320

Memperbarui:

Solusi: gunakan properti windowActionModeOverlay . Atur ini dalam tema Anda:

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

dan actionmode akan ditampilkan di atas panel tindakan alih-alih menekannya. (Jika Anda tidak menggunakan AppCompat terbaru maka Anda perlu menambahkan awalan "android:" ke properti). Ini pada dasarnya membuat AppCompat tahu bahwa Anda memiliki bilah alat yang terletak di bagian atas layar dan harus menggambar ActionMode di atasnya.


Jawaban lama / solusi:

Saya mengalami masalah yang sama. Apa pun tema yang saya tetapkan, selalu menekan Toolbar yang saya tetapkan sebagai ActionBar. Saya mencoba dengan dan tanpa perpustakaan pendukung, tetapi itu tidak masalah.

Sayangnya saya tidak dapat memperbaikinya jadi saya telah membangun solusi. Di saya ActionModeCallback, onCreateActionModesaya menyembunyikan bilah tindakan:

actionBarToolbar.setVisibility(View.GONE);

dan di onDestroyActionModesaya tunjukkan lagi:

actionBarToolbar.setVisibility(View.VISIBLE);

Penyembunyian / tampilan terjadi sangat cepat sehingga tidak terlihat pada perangkat pengujian saya. Tentu saja ada sisi negatifnya: meskipun animasi enter masih berfungsi, animasi keluar dari panel tindakan kontekstual hilang karena Toolbar segera muncul. Tetapi sampai kita menemukan solusi yang lebih baik saya kira kita terjebak dengan ini.


(Aktivitas saya sebenarnya memperluas BaseActivitykelas khusus yang memiliki metode yang disebut getActionBarToolbar(), diambil dari kode sumber aplikasi Google I / O 2014 , jadi saya bisa dengan mudah mendapatkan mengambil Bilah Alat:

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

Sayang sekali aplikasi I / O tidak menggunakan bilah tindakan kontekstual.)

Yakub Ras
sumber
Ya, ini adalah satu-satunya solusi yang bisa saya datangi juga. Namun, ada beberapa kasus ketika ActionBar Kontekstual terjadi dari sistem (misalnya di WebView atau dengan EditText). Untuk siapa Anda tidak mendapatkan panggilan balik. Jadi, bagaimana Anda akan menunjukkan / menyembunyikannya untuk itu? (Atau saya salah dan Anda bisa, pada kenyataannya, mendapatkan callback untuk CAB dengan itu)?
ariets
1
Ya, Anda dapat TextView.setCustomSelectionActionModeCallback () untuk itu, seperti yang dijelaskan Aleksandar dalam jawabannya.
Jacob Ras
1
Oh, sudah tidak dapat memperbarui komentar saya lagi. Tambahan kecil: sepertinya setCustomSelectionActionModeCallback tidak dapat digunakan dengan ActionModeCallback dari perpustakaan dukungan. Saya menggunakan centang VERSION.SDK_INT untuk mengaturnya. Masih perlu menguji apakah masalah juga terjadi pada perangkat pra-Honeycomb.
Jacob Ras
@ariet, silakan lihat jawaban saya yang diperbarui. Saya merasa agak kesal karena telah benar-benar melupakan properti itu, tetapi setidaknya kita dapat menyingkirkan solusinya sekarang ;-)
Jacob Ras
1
Lucu saya menggunakan yang terbaru (kompilasi 'com.android.support:appcompat-v7:22.0.0') tetapi saya harus meninggalkan android: bagian agar bisa berfungsi ...
Warpzit
16

Jangan memulainya pada aktivitas Anda, tetapi pada bilah alat Anda. Dalam aktivitas Anda:

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

dan Anda harus menggunakan

<item name="windowActionModeOverlay">true</item>
jujur
sumber
bagi saya itu untuk android.support.v7.app.ActionBar
Frank
Saya mendapatkan kesalahan ini-> startActionMode (android.view.ActionMode.Callback) di View tidak dapat diterapkan ke (android.support.v7.view.ActionMode.Callback)
Faheem
Ah, baiklah. Versi min saya tidak lebih kecil dari 11. Jadi saya bisa menggunakan android.view.ActionMode. Callback di android.support.v7.widget.Toolbar, saya tidak pernah menggunakan android.support.v7.view.ActionMode.Callback.
Frank
Perlu disebutkan AppCompatActivity.startSupportActionMode(callback), untuk mendapatkan kompatibilitas dengan atribut seperti app:iconTintdi item menu xmls.
geekley
14

Hanya tambahan kecil: Untuk

<item name="windowActionModeOverlay">true</item>
untuk bekerja, penting untuk memanggil super.onCreate(savedInstanceState) SEBELUM memanggil setContentView(R.layout.your_activity)aktivitas Anda. Ini benar-benar membuat perbedaan dalam hal ini!

Daniel Veihelmann
sumber
11

Dalam kasus saya, <item name="windowActionModeOverlay">true</item>tidak bekerja, tapi pekerjaan ini: <item name="android:windowActionModeOverlay">true</item>, yang androidadalah kuncinya.

Jenkyn
sumber
8
Anda menggunakan <item name="windowActionModeOverlay">true</item>dengan appcompat toolbar, jika tidak Anda menggunakan androidnamespace.
Javier Mendonça
tidak ada gunanya bagi saya di tata letak saya menambahkan toolbar, dalam aktivitas menginisialisasi toolbar dan setupport benar dilakukan tolong bantu saya
Harsha
<item name = "windowActionModeOverlay"> true </item> berfungsi seperti yang diharapkan!
Francois
8

Solusi Jacob bekerja untuk saya tetapi ActionBar kontekstual transparan dan Toolbar terlihat melaluinya. Ini dapat diatasi sebagai berikut:

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

Tema "AppTheme.Base" harus menjadi tema yang diterapkan pada Bilah Alat.

Lebih detail tentang styling ActionBar kontekstual:

cara Menyesuaikan Bilah Tindakan Kontekstual menggunakan appCompat dalam desain material

Pete
sumber
0

Metode yang sangat berguna untuk membawa bilah alat ke depan toolbar.bringToFront()

kunal.c
sumber
2
View.bringToFront()adalah operasi yang sangat berat dan umumnya harus dihindari dengan biaya berapa pun.
dominus
Anda benar, tetapi untuk animasi misalnya atas ke bawah layar akan tumpang tindih toolbar. Karenanya kita perlu menggunakan toolbar.bringToFront () untuk menghidupkan di bawah toolbar. Jika ada cara alternatif yang dapat Anda bagikan
:)
0

Tambahan kecil lainnya: pastikan untuk mengatur setidaknya layar kosong dalam aktivitas melalui setContentView(R.layout.empty_screen)jika Anda memuat seluruh ui dalam fragmen ( ft.replace(android.R.id.content, fragment)).

Andreas Wenger
sumber