Barra de herramientas centrada en la imagen


Usando el último android.support.v7.widget.Toolbar quiero centrar una imagen en la barra de herramientas, pero se mantiene a la izquierda.

La mejor manera para mí sería usar el método toolbar.setLogo() y centrar el logotipo, pero no veo ninguna manera de hacerlo.

Utilizo un diseño para el Toolbar:

  <android.support.v7.widget.Toolbar style="@style/ToolBarStyle"
                                   xmlns:android="http://schemas.android.com/apk/res/android"
                                   android:layout_width="match_parent"
                                   android:layout_height="wrap_content"
                                   android:background="?attr/colorPrimary"
                                   android:minHeight="@dimen/abc_action_bar_default_height_material">

</android.support.v7.widget.Toolbar>

¿Hay alguna posibilidad de añadir una imagen (logo) a la barra de herramientas y centrarla? ¿programáticamente o en el diseño?

Author: Vasily Kabunov, 2014-12-17

7 answers

La barra de herramientas es solo un ViewGroup, puede personalizar tanto como desee.

Prueba esto:

<android.support.v7.widget.Toolbar
   style="@style/ToolBarStyle"
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="?attr/colorPrimary"
   android:minHeight="@dimen/abc_action_bar_default_height_material">

    <ImageView
        android:layout_width="wrap_content"
        android:contentDescription="@string/logo"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher"/>

 </android.support.v7.widget.Toolbar>

Esto debería traer su ImageView en el centro de la barra de herramientas.

 112
Author: Abhinav Puri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-17 21:01:11

Si tiene alguna vista y no puede centrar el logotipo, será porque el centrado se basa en el espacio restante, no en toda la barra de herramientas.

Para garantizar que el logotipo esté centrado, intente usar una lista de capas como fondo de su barra de herramientas en lugar de intentar usar una imagen como vista.

Barra de herramientas.xml

<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/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@drawable/toolbar_background"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
    app:layout_scrollFlags="scroll|enterAlways"
    app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>

Toolbar_background.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <shape android:shape="rectangle">
      <solid android:color="@color/colorPrimary" />
    </shape>
  </item>
  <item>
    <bitmap android:src="@drawable/logo" android:gravity="center" />
  </item>
</layer-list>

Eso debería asegurar un logotipo centrado, con un color de fondo específico.

 30
Author: Blueberry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-19 07:58:04

Esta no es la mejor solución, pero es una solución que funciona incluso cuando tiene un botón o un elemento de menú.

Intenta

<FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <android.support.v7.widget.Toolbar
       style="@style/ToolBarStyle"
       xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="?attr/colorPrimary"
       android:minHeight="@dimen/abc_action_bar_default_height_material"/>

    <ImageView
        android:layout_width="wrap_content"
        android:contentDescription="@string/logo"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/ic_launcher"/>

</FrameLayout>
 6
Author: Rubin Yoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-22 20:22:18

Tuve un problema similar. Traté de usar el enfoque de lista de capas que sugirió Blueberry, pero una vez que puse un activo de alta resolución para el logotipo, la solución ya no funcionó. Un mapa de bits en una lista de capas tiene un error: Ampliará las imágenes más pequeñas para que se ajusten al espacio, pero no reducirá las imágenes más grandes. Por lo tanto, siempre y cuando esté de acuerdo con el uso de imágenes pequeñas que se ven granuladas/pixeladas cuando se agrandan, la lista de capas funciona bien.

Para resolver este problema y tener un logotipo de alta resolución centrado, eliminé completamente el atributo android:background de la barra de herramientas, agregué android:background="?attr/colorPrimary" a mi padre AppBarLayout y luego arrojé este terrible código al método onCreate de mi actividad:

    final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    ActionBar ab = getSupportActionBar();
    if (ab != null && toolbar != null)
    {
        // Hide the title text.
        ab.setDisplayShowTitleEnabled(false);

        // Convert and show the logo.
        toolbar.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
        {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
            {
                ActionBar ab = getSupportActionBar();
                if (ab != null)
                {
                    Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.logo);
                    Bitmap bmp2 = Bitmap.createBitmap(toolbar.getWidth(), toolbar.getHeight(), bmp.getConfig());
                    Bitmap bmp3 = Bitmap.createScaledBitmap(bmp, bmp.getWidth() * toolbar.getHeight() / bmp.getHeight(), toolbar.getHeight(), true);
                    Canvas canvas = new Canvas(bmp2);
                    canvas.drawBitmap(bmp3, (toolbar.getWidth() / 2) - (bmp3.getWidth() / 2), 0, null);
                    BitmapDrawable background = new BitmapDrawable(getResources(), bmp2);
                    ab.setBackgroundDrawable(background);
                }
            }
        });
    }

Funciona creando un lienzo del tamaño de la barra de herramientas y una versión a escala de proporción del logotipo, dibujando el logotipo recién redimensionado en el lienzo en el centro y, finalmente, estableciendo el mapa de bits que se dibuja como fondo de la barra de acciones.

En el lado positivo, este enfoque le da control total sobre la colocación, dimensionamiento, etc. No se limita a lo que se puede hacer en XML. Es terrible porque se llama con bastante regularidad cada vez que cambia el diseño de la barra de herramientas, lo que significa que hay implicaciones de rendimiento. Pero, cuando su equipo de diseño (que no se preocupa por lo primero con respecto al Diseño de Materiales) le pide que tenga un logotipo de fondo y pierda cinco horas buscando la solución anterior, el rendimiento deja de importar, solo quiere que la maldita cosa funcione. El código anterior apesta bastante mal a desesperación.

Voy a dejar que alguien más capaz que yo en el desarrollo de Android señalar que "Lo estoy haciendo mal" y solucionar cualquier problema de rendimiento/errores que hay con el código anterior. No cambia el hecho de que layer-list bitmap está roto y este es un hack (que no debería existir) para corregir un error estúpido (que tampoco debería existir) en Android.

 2
Author: maddog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-21 18:19:39

Si el usuario establece:

activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); activity.getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_iconmenu);

Y después hacer algo como

<Toolbar ... >
   <ImageView ...>
   </ImageView>
</Toolbar>

A continuación, la imagen dentro de la barra de herramientas no se centrará así causa botón de inicio comer un poco de espacio de diseño.El centro horizontal de la imagen estará sesgado en el icono de inicio width.So la mejor solución:
1.Crear 9-parche png de la imagen original .png resource.
2.Cree un elemento de diseño a partir de 9-patch con xml usando layer-list como ejemplo toolbar_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/white"/><!-- fill color under image(optional) -->
    <item>
        <nine-patch
        android:src="@drawable/toolbar_image" />
    </item>
</layer-list>


A continuación, establecer toolbar_background resource como fondo en el elemento Toolbar:

<Toolbar android:background="toolbar_background" ...>
</Toolbar>


Eso es todo.

 1
Author: artyom mamaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-07 22:27:37

Si necesitas centrar un diseño más complicado en la barra de herramientas que solo una imagen, esto es lo que coloqué en el onCreate de mi actividad():

mToolbar.addOnLayoutChangeListener(
            new View.OnLayoutChangeListener() {
                @Override
                public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) {
                    // Push layout to the center
                    int toolbarCenterX = (int) (mToolbar.getWidth() / 2.0 - mMiddleToolbarLayout.getWidth() / 2.0));
                    if(mMiddleToolbarLayout.getX() != toolbarCenterX) {
                        mMiddleToolbarLayout.setX(toolbarCenterX);
                    }
                }
            }
    );

Cuando se llama onLayoutChange, el ancho de su diseño ya está determinado, por lo que simplemente lo empuja hacia el centro.

NOTA: Es importante solo centrar la barra de herramientas (ver la condición if) cuando no está centrada, de lo contrario esta devolución de llamada sería re-llamada en un bucle infinito.

El XML el archivo se verá así:

<android.support.v7.widget.Toolbar
...
>
    <LinearLayout
        android:id="@+id/middle_toolbar_layout"
        ...
    >
</android.support.v7.widget.Toolbar>
 0
Author: johnny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-11 04:47:04

Puedes usar este código:

     <android.support.v7.widget.Toolbar

        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"

        android:background="?attr/colorPrimary"

        app:popupTheme="@style/AppTheme.PopupOverlay">


        <ImageView
            android:layout_width="250dp"
            android:layout_height="match_parent"
            android:src="@drawable/apptitle"/>
 0
Author: Matin Gdz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-06 17:17:34