Android Lollipop, tampilan kustom AppCompat ActionBar tidak menggunakan lebar layar secara keseluruhan

97

Jadi, saya baru saja memperbarui basis kode saya ke Lollipop, dan saya mengalami masalah dengan Bilah Tindakan. Saya menggunakan AppCompat dan ActionBarActivity, dan meluaskan tampilan kustom. Tampaknya tampilan kustom tidak lagi memenuhi seluruh lebar layar, meninggalkan garis tipis di sebelah kiri

Membangun dengan 19 Cara yang dulu terlihat

Membangun dengan 21 Cara tampilannya sekarang

Ini adalah kode yang saya gunakan untuk menyiapkan Bilah Tindakan. Ada yang punya ide?

final ActionBar actionBar = getSupportActionBar();
if(actionBar != null) {
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setDisplayShowHomeEnabled(false);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setDisplayShowCustomEnabled(true);
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
    actionBar.setCustomView(R.layout.action_bar_content_search_custom_view);
    actionBar.setBackgroundDrawable(null);
    // actionBar.setStackedBackgroundDrawable(null);
    TextView title = (TextView) actionBar.getCustomView().findViewById(R.id.action_bar_title);
    title.setText(R.string.youtube);
    ImageView back = (ImageView) actionBar.getCustomView().findViewById(R.id.action_bar_back);
    back.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            finish();
        }
    });
}

Edit

Mengambil tampilan kustom dan mengubah latar belakang sekarang memakan seluruh lebar. Jadi masalahnya adalah, bagaimana kita bisa membuat CustomView menjadi seluruh lebar ActionBar?

Stevie Kideckel
sumber
Jika Anda sementara mengomentari bagian tampilan kustom, apakah berperilaku lebih baik? Jika tidak, saya akan condong ke arah ini yang mungkin berasal dari tema Anda.
CommonsWare
Saya menghapus tampilan khusus, dan mengatur latar belakangnya sebagai latar belakang yang dapat digambar dari ActionBar dan latar belakang mengambil seluruh lebar sekarang
Stevie Kideckel
Anda mungkin mengintip aktivitas Anda dalam Hierarchy View, baik dengan atau tanpa tampilan kustom, dan melihat apakah Anda bisa menentukan aturan tata letak apa yang bergeser sebagai hasil dari tampilan kustom. Mungkin saja ini bug di yang baru appcompat-v7.
CommonsWare
Tampak bagi saya itu adalah tempat yang dicadangkan ImageView. Coba nonaktifkan sebagai permulaan.
Nikola Despotoski
1
Hai, tampaknya ini adalah solusi yang baik agar tampilan khusus mengambil seluruh lebar. Saya mengalaminya tidak berkembang, bahkan dengan pengaturan bobot tata letak. lihat di sini: stackoverflow.com/a/20794736/581574
ratana

Jawaban:

111

Sepertinya ini disebabkan oleh perubahan terbaru pada ActionBar terbaru pada appcompat-v7pembaruan terkini . Sepertinya ada perubahan signifikan pada cara Anda menangani bilah tindakan.

Saya menghadapi masalah yang sama dan setelah membaca ActionBar dokumentasi , dan terutama kutipan berikut saya menemukan solusinya.

Mulai Android L (API level 21), panel tindakan dapat diwakili oleh widget Toolbar apa pun dalam tata letak aplikasi. Aplikasi mungkin memberi sinyal pada Aktivitas yang Toolbar harus diperlakukan sebagai panel tindakan Aktivitas. Aktivitas yang menggunakan fitur ini harus menggunakan salah satu tema .NoActionBar yang disediakan, menyetel atribut windowActionBar ke false atau sebaliknya tidak meminta fitur jendela.

Cara saya melihatnya, AppCompattema diubah dan di satu sisi tampaknya merusak beberapa hal tetapi memberikan lebih banyak fleksibilitas di sisi lain. Saya merekomendasikan mengikuti langkah-langkah ini:

  1. Gunakan .NoActionBargaya dalam aktivitas Anda seperti yang dijelaskan dalam kutipan di atas
  2. Tambahkan a android.support.v7.widget.Toolbarke tata letak Aktivitas Anda
  3. Atur app:contentInsetStart="0dp"atributnya. Ini adalah masalah utama dengan margin yang Anda gambarkan dalam pertanyaan Anda
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/actionBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:contentInsetEnd="0dp"
    app:contentInsetStart="0dp" >
</android.support.v7.widget.Toolbar>

Biasanya disarankan agar Anda melakukannya dalam file tata letak terpisah dan menggunakannya includedalam tata letak aktivitas sehingga Anda hanya perlu menyesuaikan Toolbar di satu tempat jika digunakan dalam banyak aktivitas.

<include layout="@layout/view_action_bar" />
  1. Gunakan findViewByIddan setSupportActionBardalam Aktivitas Anda onCreateuntuksignal to the Activity which Toolbar should be treated as the Activity's action bar
Toolbar actionBar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(actionBar);
  1. Setelah Anda melakukannya, semua tindakan yang ditambahkan onCreateOptionsMenuakan ditambahkan ke bilah alat dan akan diperlakukan sebagai bilah tindakan aktivitas.
  2. Sesuaikan lebih lanjut Toolbar sesuai keinginan (Tambahkan tampilan anak, dll.)
Muzikant
sumber
1
Saya mencoba menggunakan Toolbar dengan panel samping navigasi, namun saya mendapatkan kesalahanError inflating class fragment
Ahmed Nawaz
Semua kode yang relevan dibagikan pada jawabannya. Sepertinya Anda harus memulai pertanyaan baru untuk kasus Anda karena sepertinya ada masalah yang berbeda.
Muzikant
Terima kasih. Saya memecahkan masalah dengan mengganti actionbar dengan Toolbar.
Ahmed Nawaz
9
Anda tidak boleh menggunakan nama paket eksplisit dalam deklarasi namespace. Gunakanxmlns:app="http://schemas.android.com/apk/res-auto"
Liminal
1
Tidak perlu setCustomView. Buat saja file tata letak dengan widget yang ingin Anda sertakan di toolbar (misalnya, tambahkan tampilan anak ke file tata letak yang dijelaskan di bagian 3 jawaban)
Muzikant
51

Alih-alih melakukan begitu banyak pekerjaan seperti yang disebutkan oleh Muzikant dan menyukai jawaban ini

    getSupportActionBar().setDisplayShowHomeEnabled(false);
    getSupportActionBar().setDisplayShowTitleEnabled(false);
    getSupportActionBar().setBackgroundDrawable(new ColorDrawable(Color.WHITE));
    LayoutInflater mInflater = LayoutInflater.from(this);

    View mCustomView = mInflater.inflate(R.layout.action_bar_home, null);
    getSupportActionBar().setCustomView(mCustomView);
    getSupportActionBar().setDisplayShowCustomEnabled(true);
    Toolbar parent =(Toolbar) mCustomView.getParent();//first get parent toolbar of current action bar 
    parent.setContentInsetsAbsolute(0,0);// set padding programmatically to 0dp

Anda harus menambahkan hanya dua baris kode terakhir untuk menyelesaikan masalah Anda.

Saya harap ini dapat membantu Anda dan orang lain.

UPDATE: Setelah melakukan beberapa penelitian, saya menemukan bahwa solusi ini tidak akan berfungsi dalam beberapa kasus. Celah sisi kiri (HOME atau BACK) akan dihilangkan, tetapi celah sisi kanan (MENU) akan tetap apa adanya. Di bawah ini adalah solusi untuk kasus ini.

View v = getSupportActionBar().getCustomView();
LayoutParams lp = v.getLayoutParams();
lp.width = LayoutParams.MATCH_PARENT;
v.setLayoutParams(lp);

Tambahkan empat baris ini ke kode di atas, sehingga celah sisi kanan juga dihapus dari bilah tindakan dukungan.

Amrut Bidri
sumber
Terima kasih! Terima kasih! 2 baris terakhir adalah yang saya cari!
digitalmidges
Di mana kita menambahkan baris ini? Setelah bagian Toolbar?
Zen
1
@summers ya tambahkan segera setelah kode toolbar.
Amrut Bidri
31

Saya pikir Anda juga bisa melakukannya dengan gaya. coba ini. mengujinya di kitkat

<style name="AppTheme" parent="Theme.AppCompat">
  <item name="toolbarStyle">@style/AppThemeToolbar</item>
</style>

<style name="AppThemeToolbar" parent="Widget.AppCompat.Toolbar" >
  <item name="contentInsetStart">0dp</item>
</style>
GDA
sumber
1
Jawaban ini salah: android: contentInsetStart membutuhkan API level 21 (min saat ini adalah 14)
mr.boyfox
Tapi, idiom sangat bagus! Anda perlu menulis gaya secara terpisah untuk api 21 dan versi lama.
Tuan Boyfox
Ini adalah jawaban yang benar untuk menghilangkan margin kiri jika Anda masih menggunakan bilah tindakan default.
Tooroop
Ini memang berhasil! Dengan dukungan lib versi terbaru, saya rasa Anda tidak perlu mendeklarasikan atribut dua kali (android: ones tidak diperlukan).
Direksi
Saya telah mencari masalah ini dan ketika saya menemukan jawaban Anda, saya melihat bahwa saya sudah memilihnya! Jadi terima kasih dua kali.
pengguna1732313
8

Tak satu pun dari jawaban lain yang berhasil untuk saya, jadi saya melihat gaya AppCompat v7 yang sebenarnya, yang ditemukan di sini .

Jika Anda melihat gaya Base.Widget.AppCompat.ActionBar, ini memiliki:

<item name="contentInsetStart">@dimen/abc_action_bar_content_inset_material</item>
<item name="contentInsetEnd">@dimen/abc_action_bar_content_inset_material</item>

Jadi jelas kita hanya perlu mengganti properti tersebut dengan gaya bilah tindakan kita sendiri:

<style name="ActionBar" parent="@style/Base.Widget.AppCompat.ActionBar">
        <item name="contentInsetStart">0dp</item>
        <item name="contentInsetEnd">0dp</item>
</style>

Ini berhasil dengan baik bagi saya, semoga membantu orang lain juga.

Justin
sumber
Ya, karena jawaban yang dipilih menyatakan, kuncinya adalah atribut contentInsetStart dan contentInsetEnd dari ActionBar / Toolbar. Ini valid untuk menentukan gaya Anda sendiri, tetapi Anda juga dapat mengaturnya ke 0dp pada atribut Toolbar di xml Anda
Stevie Kideckel
1

Setelah banyak membenturkan kepala saya ke monitor, ini berhasil untuk saya

 Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
        toolbar.setContentInsetStartWithNavigation(0);
        toolbar.setContentInsetEndWithActions(0);
        toolbar.setContentInsetsAbsolute(0, 0);
        toolbar.setPadding(0, 0, 0, 0);

GetCustomView (). GetParent () adalah triknya

pengguna330844
sumber
0

Saya baru saja mengalami masalah ini hari ini juga, kemudian saya menemukan bahwa saya mengalaminya res/values-v21/styles.xml di dalam proyek saya yang dibuat secara otomatis oleh Android Studio dan itulah penyebabnya.

Mengapa?

Karena konten saya res/values-v21/styles.xmladalah:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="BaseAppTheme" parent="android:Theme.Material.Light">
    </style>
</resources>

Dan saya res/values/styles.xmlberisi sesuatu seperti:

<style name="BaseAppTheme" parent="android:Theme.Holo.Light">
    <!-- Customize your theme here. -->
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:soundEffectsEnabled">false</item>
</style>

Kemudian ketika saya menjalankan aplikasi saya di Lollipop, res/values-v21/styles.xmlitu digunakan, dan itu menyebabkan masalah persis yang dimiliki OP. Jadi saya sampai pada perbaikan sederhana hanya menghapus:

    <style name="BaseAppTheme" parent="android:Theme.Material.Light">
    </style>

di res/values-v21/styles.xml

Leo
sumber
0

ke titik:

 ActionBar actionBar = getSupportActionBar();
                actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
                actionBar.setCustomView(R.layout.actionbar_layout);
                Toolbar toolbar = (Toolbar) actionBar.getCustomView().getParent();
                    toolbar.setContentInsetsAbsolute(0, 0);
                    toolbar.setPadding(0, 0, 0, 0);

pastikan mengimpor bilah alat yang benar - android.support.v7.widget.Toolbar;

Salman Anjum
sumber
0

Tuliskan dua baris ini sebagai tambahan kode Anda

Toolbar toolbar=(Toolbar)viewActionBar.getParent();
toolbar.setContentInsetsAbsolute(0,0);
Anisuzzaman Babla
sumber