La vista personalizada de Android Lollipop, AppCompat ActionBar no ocupa todo el ancho de la pantalla


97

Entonces, acabo de actualizar mi base de código a Lollipop y tengo problemas con la barra de acción. Estoy usando AppCompat y ActionBarActivity e inflando una vista personalizada. Parece que la vista personalizada ya no ocupa todo el ancho de la pantalla, dejando una delgada franja a la izquierda

Edificio con 19 Como solía verse

Edificio con 21 Como se ve ahora

Este es el código que estoy usando para configurar la barra de acción. ¿Alguien tiene alguna 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();
        }
    });
}

Editar

Sacar la vista personalizada y cambiar el fondo ahora ocupa todo el ancho. Entonces, el problema es, ¿cómo podemos hacer que un CustomView ocupe todo el ancho de ActionBar?


Si comenta temporalmente las partes de la vista personalizada, ¿se comporta mejor? De lo contrario, me inclinaría hacia esto, tal vez proveniente de su tema.
CommonsWare

Eliminé la vista personalizada y configuré su fondo como el diseño de fondo de ActionBar y el fondo ocupa todo el ancho ahora
Stevie Kideckel

Puede echar un vistazo a su actividad en la Vista de jerarquía, tanto con la vista personalizada como sin ella, y ver si puede determinar qué reglas de diseño están cambiando como resultado de la vista personalizada. Es posible que esto sea un error en el nuevoappcompat-v7 .
CommonsWare

Me parece que es el lugar reservado para arriba ImageView. Intente desactivarlo para empezar.
Nikola Despotoski

1
Hola, parece que esta es una buena solución para que la vista personalizada tome todo el ancho. Estaba experimentando que no se expandía, incluso con los pesos de diseño establecidos. ver aquí: stackoverflow.com/a/20794736/581574
ratana

Respuestas:


111

Parece que esto se debe a los últimos cambios ActionBaren la appcompat-v7actualización reciente . Parece que hay cambios significativos en cómo debe manejar las barras de acción.

Enfrenté el mismo problema y después de leer la ActionBardocumentación , y especialmente la siguiente cita, encontré una solución.

A partir de Android L (nivel de API 21), la barra de acciones puede estar representada por cualquier widget de barra de herramientas dentro del diseño de la aplicación. La aplicación puede indicar a la Actividad qué barra de herramientas debe tratarse como la barra de acción de la Actividad. Las actividades que utilizan esta función deben utilizar uno de los temas .NoActionBar suministrados, establecer el atributo windowActionBar en falso o no solicitar la función de ventana.

A mi modo de ver, los AppCompattemas se cambiaron y por un lado parecían romper algunas cosas pero por el otro brindar mucha más flexibilidad. Recomiendo seguir estos pasos:

  1. Use .NoActionBarestilo en su actividad como se describe en la cita anterior
  2. Agregue un android.support.v7.widget.Toolbardiseño a su actividad
  3. Establezca el app:contentInsetStart="0dp"atributo. Este es el problema principal con el margen que describe en su pregunta.
<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>

Por lo general, se recomienda que lo haga en un archivo de diseño separado y lo use includeen el diseño de su actividad, por lo que solo necesitará personalizar la barra de herramientas en un lugar si se usa en varias actividades

<include layout="@layout/view_action_bar" />
  1. Utilice findViewByIdy setSupportActionBaren su Actividad onCreateparasignal 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 vez que lo haga, todas las acciones agregadas onCreateOptionsMenuse agregarán a la barra de herramientas y se tratará como la barra de acciones de la actividad.
  2. Personalice aún más la barra de herramientas como desee (agregue vistas secundarias, etc.)

1
Estoy tratando de usar la barra de herramientas con el cajón de navegación, sin embargo, recibo un errorError inflating class fragment
Ahmed Nawaz

Todo el código relevante se comparte en la respuesta. Parece que debería comenzar una nueva pregunta para su caso, ya que parece un problema diferente.
Muzikant

Gracias. Resolví el problema reemplazando la barra de acción con la barra de herramientas.
Ahmed Nawaz

9
No debe utilizar nombres de paquetes explícitos en las declaraciones del espacio de nombres. Usoxmlns:app="http://schemas.android.com/apk/res-auto"
Liminal

1
No es necesario setCustomView. Simplemente cree un archivo de diseño con los widgets que desea incluir en su barra de herramientas (por ejemplo, agregue vistas secundarias al archivo de diseño descrito en la sección 3 de la respuesta)
Muzikant

51

En lugar de hacer tanto trabajo como lo menciona Muzikant y como esta respuesta

    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

Debe agregar solo las dos últimas líneas de código para resolver su problema.

Espero que esto pueda ayudarlo a usted y a cualquier otra persona.

ACTUALIZACIÓN: Después de investigar un poco, descubrí que esta solución no funcionará en algunos casos. El espacio del lado izquierdo (INICIO o ATRÁS) se eliminará con esto, pero el espacio del lado derecho (MENÚ) permanecerá como está. A continuación se muestra la solución en estos casos.

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

Agregue estas cuatro líneas al código anterior, de modo que el espacio del lado derecho también se elimine de la barra de acción de soporte.


¡Gracias! ¡Gracias! ¡Las últimas 2 líneas eran lo que estaba buscando!
digitalmidges

¿Dónde agregamos estas líneas? ¿Después de la parte de la barra de herramientas?
Zen

1
@summers sí, agréguelos inmediatamente después del código de la barra de herramientas.
Amrut Bidri

31

Creo que también puedes hacer eso en estilos. prueba esto. lo probé en 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
Esta respuesta es incorrecta: android: contentInsetStart requiere nivel de API 21 (el mínimo actual es 14)
mr.boyfox

¡Pero, modismo muy bueno! Necesita escribir estilo por separado para api 21 y versiones anteriores.
mr.boyfox

Esta es la respuesta correcta para eliminar el margen izquierdo si todavía está usando la barra de acción predeterminada.
Tooroop

¡Esto funciona de verdad! Con la última versión de la biblioteca de soporte, creo que no es necesario declarar los atributos dos veces (los android: ones no son necesarios).
BoD

He estado buscando este problema y cuando encontré su respuesta, ¡veo que ya lo voté a favor! Así que gracias dos veces.
user1732313

8

Ninguna de las otras respuestas me funcionó, así que eché un vistazo a los estilos reales de AppCompat v7, que se encuentran aquí .

Si observa el estilo Base.Widget.AppCompat.ActionBar, tiene:

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

Entonces, obviamente, solo necesitamos anular esas propiedades en nuestro propio estilo de barra de acción:

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

Esto funcionó muy bien para mí, espero que también ayude a otros.


Sí, como dice la respuesta elegida, la clave son los atributos contentInsetStart y contentInsetEnd de ActionBar / Toolbar. Es válido definir su propio estilo, pero también puede establecerlos en 0dp en los atributos de la barra de herramientas en su xml
Stevie Kideckel

1

Después de mucho golpearme la cabeza contra el monitor, esto funcionó para mí.

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

GetCustomView (). GetParent () es lo que hizo el truco


0

También encontré este problema hoy, luego descubrí que estaba teniendo res/values-v21/styles.xml dentro de mi proyecto que fue generado automáticamente por Android Studio y esa es la causa.

¿Por qué?

Porque mi res/values-v21/styles.xmlcontenido era:

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

Y mi res/values/styles.xmlcontenido algo como:

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

Luego, cuando ejecuté mi aplicación en Lollipop, res/values-v21/styles.xmlse usó y eso causó el problema exacto que tenía OP. Así que llegué a una solución simple: simplemente eliminar:

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

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

asegúrese de importar la barra de herramientas correcta - android.support.v7.widget.Toolbar;


0

Escriba estas dos líneas además de su código

Toolbar toolbar=(Toolbar)viewActionBar.getParent();
toolbar.setContentInsetsAbsolute(0,0);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.