web-dev-qa-db-fra.com

Image de la barre d'outils centrée

En utilisant le dernier Android.support.v7.widget.Toolbar, je souhaite centrer une image dans la barre d’outils, mais elle reste à gauche.

Le meilleur moyen pour moi serait d’utiliser la méthode toolbar.setLogo() et de centrer le logo, mais je ne vois aucun moyen de le faire.

J'utilise une mise en page pour la 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>

Est-il possible d’ajouter une image (logo) à la barre d’outils et de la centrer? Par programme ou dans la mise en page?

56
Nicolas Oz

La barre d’outils est juste un ViewGroup, que vous pouvez personnaliser autant que vous le souhaitez.

Essaye ça : 

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

Cela devrait amener votre imageView au centre de la barre d’outils.

117
Abhinav Puri

Si vous avez une vue et ne parvenez pas à centrer le logo, ce sera parce que le centrage est basé sur l'espace restant et non sur la barre d'outils complète.

Pour vous assurer que le logo est centré, essayez d’utiliser une liste de calques comme arrière-plan de votre barre d’outils plutôt que d’utiliser une image comme vue.

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

Cela devrait assurer un logo centré, avec une couleur d'arrière-plan spécifique.

32
Blueberry

Ce n'est pas la meilleure solution, mais c'est une solution de contournement qui fonctionne même lorsque vous avez un bouton ou un élément de menu en place.

essayer

<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>
8
Rubin Yoo

J'avais un problème similaire. J'ai essayé d'utiliser l'approche de liste de couches proposée par Blueberry, mais une fois que j'ai intégré un actif de résolution élevée pour le logo, la solution ne fonctionnait plus. Un bitmap dans une liste de calques présente un bogue: il agrandira les images plus petites pour s’adapter à l’espace, mais ne réduira pas les images plus grandes. Donc, tant que vous êtes en mesure d’utiliser des images minuscules qui paraissent granuleuses/pixelisées lorsqu’elles sont agrandies, la liste des calques fonctionne bien.

Pour résoudre ce problème et avoir un logo centré en haute résolution, j'ai complètement supprimé l'attribut Android:background de la barre d'outils, ajouté Android:background="?attr/colorPrimary" à mon parent AppBarLayout et ai ensuite jeté ce code dans la méthode onCreate de mon activité:

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

Pour créer un canevas de la taille de la barre d’outils et une version du logo à l’échelle du ratio, dessinez le logo redimensionné sur le canevas au centre, puis définissez le bitmap utilisé comme arrière-plan de la barre d’action.

Sur le plan positif, cette approche vous donne un contrôle total sur le placement, le dimensionnement, etc. Non limité à tout ce que vous pouvez faire en XML. C’est terrible car elle est appelée assez régulièrement chaque fois que la disposition de la barre d’outils change, ce qui implique des conséquences en termes de performances. Mais, lorsque votre équipe de conception vous demande (ne vous souciez pas de la première chose à propos de Material Design) d’avoir un logo d’arrière-plan et de perdre cinq heures à chercher la solution ci-dessus, les performances cessent d’importer - vous voulez simplement que la chose fonctionne. Le code ci-dessus respire le désespoir.

Je laisserai quelqu'un de plus capable que moi dans le développement d'Android faire remarquer que "je me trompe" et corriger les problèmes de performances/bugs liés au code ci-dessus. Cela ne change pas le fait que le bitmap de liste de couches est brisé et qu'il s'agit d'un hack (qui ne devrait pas exister) pour corriger un bogue stupide (qui ne devrait pas exister non plus) dans Android.

2
maddog

Si utilisateur défini:

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

et après faire quelque chose comme 

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

alors l'image dans la barre d'outils ne sera pas centrée aussi bien parce que le bouton d'accueil prendra un peu de place dans la présentation.Le centre horizontal de l'image sera biaisé sur la largeur de l'icône d'accueil.
1.Create 9-patch png à partir de votre ressource .png d’image originale.
2.Créer un dessin de 9-patch avec xml en utilisant layer-list comme exemple 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>


Définissez ensuite la ressource toolbar_background en tant qu’arrière-plan dans l’élément Toolbar:

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


C'est tout.

1
artyom mamaev

Si vous avez besoin de centrer un agencement plus compliqué dans la barre d’outils qu’une image, c’est ce que j’ai placé dans mon onCreate () : de mon activité. 

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

Lorsque onLayoutChange est appelé, la largeur de votre mise en page est déjà déterminée, il vous suffit donc de le pousser au centre.

NOTE: Il est important de ne centrer que la barre d'outils (voir la condition if) lorsqu'elle n'est pas centrée, sinon ce rappel serait rappelé dans une boucle infinie.

Le fichier XML ressemblera à ceci:

<Android.support.v7.widget.Toolbar
...
>
    <LinearLayout
        Android:id="@+id/middle_toolbar_layout"
        ...
    >
</Android.support.v7.widget.Toolbar>
0
johnny

J'aime l'approche proposée par La réponse de Ruben Yoo en raison de sa simplicité . Il est explicite, facile à suivre et conserve tous les changements de code ensemble.

Voici une version mise à jour avec quelques améliorations mineures:

<Android.support.design.widget.AppBarLayout
    Android:id="@+id/layout_app_bar"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content">

    <FrameLayout
        Android:layout_width="match_parent"
        Android:layout_height="?attr/actionBarSize">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize">
        </Android.support.v7.widget.Toolbar>

        <ImageView
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:contentDescription="@string/app_name"
            Android:scaleType="centerInside"
            Android:src="@mipmap/ic_launcher"/>
    </FrameLayout>

</Android.support.design.widget.AppBarLayout>

Changements:

  1. introduit AppBarLayout parent 
  2. taille explicite ?attr/actionBarSize fournie au cadre et à la barre d'outils
  3. ImageView correspond aux dimensions parent en largeur et hauteur
  4. logo redimensionné à centerInside
0

vous pouvez utiliser ce code:

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