Android Lollipop, la visualizzazione personalizzata AppCompat ActionBar non occupa l'intera larghezza dello schermo


97

Quindi, ho appena aggiornato la mia base di codice a Lollipop e ho problemi con la barra delle azioni. Sto usando AppCompat e ActionBarActivity e gonfio una visualizzazione personalizzata. Sembra che la visualizzazione personalizzata non occupi più l'intera larghezza dello schermo, lasciando una sottile striscia a sinistra

Edificio con 19 Il modo in cui appariva

Edificio con 21 Come sembra ora

Questo è il codice che sto usando per impostare la barra delle azioni. Qualcuno ha qualche idea?

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

modificare

La rimozione della visualizzazione personalizzata e la modifica dello sfondo ora occupano l'intera larghezza. Quindi il problema è: come possiamo fare in modo che un CustomView occupi l'intera larghezza della ActionBar?


Se si commentano temporaneamente le parti della vista personalizzata, si comporta meglio? In caso contrario, mi propenderei per questo forse derivante dal tuo tema.
CommonsWare

Ho rimosso la visualizzazione personalizzata e ho impostato lo sfondo come sfondo disegnabile della ActionBar e lo sfondo occupa l'intera larghezza ora
Stevie Kideckel

Potresti dare un'occhiata alla tua attività nella visualizzazione gerarchia, sia con che senza la visualizzazione personalizzata, e vedere se puoi determinare quali regole di layout cambiano come risultato della visualizzazione personalizzata. È possibile che questo sia un bug nel nuovo appcompat-v7.
CommonsWare

Mi sembra che sia il posto riservato a up ImageView. Prova a disabilitarlo per i principianti.
Nikola Despotoski

1
Ciao, sembra che questa sia una buona soluzione per fare in modo che la visualizzazione personalizzata occupi l'intera larghezza. Stavo sperimentando che non si espandeva, anche con i pesi del layout impostati. vedere qui: stackoverflow.com/a/20794736/581574
Ratana

Risposte:


111

Sembra che ciò sia causato dalle ultime modifiche al ActionBarrecente appcompat-v7aggiornamento. Sembra che ci siano cambiamenti significativi su come gestire le barre delle azioni.

Ho affrontato lo stesso problema e dopo aver letto il file ActionBar documentazione , e soprattutto la citazione seguente, ho trovato una soluzione.

A partire da Android L (livello API 21), la barra delle azioni può essere rappresentata da qualsiasi widget della barra degli strumenti all'interno del layout dell'applicazione. L'applicazione può segnalare all'attività quale barra degli strumenti deve essere trattata come barra delle azioni dell'attività. Le attività che utilizzano questa funzione devono utilizzare uno dei temi .NoActionBar forniti, impostare l'attributo windowActionBar su false o altrimenti non richiedere la funzione finestra.

Per come la vedo io, i AppCompattemi sono stati cambiati e da un lato sembrava rompere alcune cose, ma dall'altra fornire molta più flessibilità. Consiglio di seguire questi passaggi:

  1. Uso .NoActionBar stile nella tua attività come descritto nella citazione sopra
  2. Aggiungere un android.support.v7.widget.Toolbar al layout delle attività
  3. Imposta l' app:contentInsetStart="0dp"attributo. Questo è il problema principale con il margine che descrivi nella tua domanda
<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>

Di solito si consiglia di farlo in un file di layout separato e di utilizzarlo includenel layout delle attività, quindi sarà necessario personalizzare la barra degli strumenti in un unico posto se utilizzato in più attività

<include layout="@layout/view_action_bar" />
  1. Usa findViewByIde setSupportActionBarnella tua attività onCreatepersignal to the Activity which Toolbar should be treated as the Activity's action bar
Toolbar actionBar = (Toolbar) findViewById(R.id.actionBar);
setSupportActionBar(actionBar);
  1. Una volta fatto ciò, tutte le azioni aggiunte onCreateOptionsMenuverranno aggiunte alla barra degli strumenti e verranno trattate come la barra delle azioni dell'attività.
  2. Personalizza ulteriormente la barra degli strumenti come desideri (aggiungi visualizzazioni figlio ecc.)

1
Sto provando a utilizzare la barra degli strumenti con il cassetto di navigazione, ma ricevo un erroreError inflating class fragment
Ahmed Nawaz

Tutto il codice rilevante è condiviso sulla risposta. Sembra che dovresti iniziare una nuova domanda per il tuo caso in quanto sembra un problema diverso.
Muzikant

Grazie. Ho risolto il problema sostituendo la barra delle azioni con la barra degli strumenti.
Ahmed Nawaz

9
Non dovresti usare nomi di pacchetto espliciti nelle dichiarazioni dello spazio dei nomi. Usaxmlns:app="http://schemas.android.com/apk/res-auto"
Liminal

1
Non ce n'è bisogno setCustomView. Basta creare un file di layout con i widget che si desidera includere nella barra degli strumenti (ad esempio, aggiungere visualizzazioni
secondarie

51

Invece di fare così tanto lavoro come menzionato da Muzikant e come questa risposta

    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

Devi aggiungere solo le ultime due righe di codice per risolvere il tuo problema.

Spero che questo possa aiutare te e chiunque altro.

AGGIORNAMENTO: Dopo aver effettuato alcune ricerche su di esso, ho scoperto che questa soluzione non funzionerà in alcuni casi. Lo spazio sul lato sinistro (HOME o BACK) verrà rimosso con questo, ma lo spazio sul lato destro (MENU) rimarrà così com'è. Di seguito è la soluzione in questi casi.

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

Aggiungi queste quattro righe al codice sopra, in modo che anche lo spazio sul lato destro venga rimosso dalla barra delle azioni di supporto.


Grazie! Grazie! le ultime 2 righe erano quello che stavo cercando!
digitalmidges

Dove aggiungiamo queste righe? Dopo la parte della barra degli strumenti?
Zen

1
@summers sì aggiungili immediatamente dopo il codice della barra degli strumenti.
Amrut Bidri

31

Penso che tu possa farlo anche con gli stili. prova questo. testato su 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>

1
Questa risposta è sbagliata: android: contentInsetStart richiede il livello API 21 (il minimo attuale è 14)
mr.boyfox

Ma, idioma molto buono! È necessario scrivere separatamente lo stile per api 21 e versioni precedenti.
mr.boyfox

Questa è la risposta corretta per rimuovere il margine sinistro se stai ancora utilizzando la barra delle azioni predefinita.
Tooroop

Funziona davvero! Con l'ultima versione della libreria di supporto, penso che non sia necessario dichiarare gli attributi due volte (quelli Android: quelli non sono necessari).
CdA

Ho cercato questo problema e quando ho trovato la tua risposta vedo che l'ho già votato! Quindi grazie due volte.
user1732313

8

Nessuna delle altre risposte ha funzionato per me, quindi ho dato un'occhiata agli stili attuali di AppCompat v7, trovati qui .

Se guardi lo stile Base.Widget.AppCompat.ActionBar, ha:

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

Quindi, ovviamente, dobbiamo solo sovrascrivere quelle proprietà nel nostro stile della barra delle azioni:

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

Questo ha funzionato alla grande per me, spero che aiuti anche gli altri.


Sì, come afferma la risposta scelta, la chiave sono gli attributi contentInsetStart e contentInsetEnd di ActionBar / Toolbar. È valido per definire il tuo stile, ma puoi anche impostarli a 0dp sugli attributi della barra degli strumenti nel tuo xml
Stevie Kideckel

1

Dopo aver sbattuto molto la testa contro il monitor, questo ha funzionato per me

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

GetCustomView (). GetParent () è ciò che ha funzionato


0

Ho riscontrato questo problema anche oggi, poi ho scoperto che stavo avendo res/values-v21/styles.xml dentro il mio progetto che è stato generato automaticamente da Android Studio e questa è la causa.

Perché?

Perché il mio res/values-v21/styles.xmlcontenuto era:

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

E il mio res/values/styles.xmlconteneva qualcosa del tipo:

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

Quindi, quando ho eseguito la mia app su Lollipop, è res/values-v21/styles.xmlstato utilizzato e questo ha causato il problema esatto di OP. Quindi sono arrivato a una soluzione semplice: eliminare:

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

nel res/values-v21/styles.xml


0

al punto:

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

assicurati di importare la barra degli strumenti giusta - android.support.v7.widget.Toolbar;


0

Scrivi queste due righe in aggiunta al tuo codice

Toolbar toolbar=(Toolbar)viewActionBar.getParent();
toolbar.setContentInsetsAbsolute(0,0);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.