webentwicklung-frage-antwort-db.com.de

Symbolleistenbild zentriert

Mit dem letzten Android.support.v7.widget.Toolbar möchte ich ein Bild in der Symbolleiste zentrieren, es bleibt jedoch auf der linken Seite.

Der beste Weg für mich wäre, die toolbar.setLogo()-Methode zu verwenden und das Logo zu zentrieren.

Ich benutze ein Layout für die 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>

Gibt es eine Möglichkeit, ein Bild (Logo) zur Werkzeugleiste hinzuzufügen und es zu zentrieren? Programmgesteuert oder im Layout?

56
Nicolas Oz

Die Symbolleiste ist nur eine Ansichtsgruppe, die Sie beliebig anpassen können.

Versuche dies : 

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

Dies sollte Ihre imageView in die Mitte der Symbolleiste bringen.

117
Abhinav Puri

Wenn Sie Ansichten haben und das Logo nicht ganz zentrieren können, liegt dies daran, dass die Zentrierung auf dem verbleibenden Platz und nicht auf der gesamten Symbolleiste basiert.

Um sicherzustellen, dass das Logo zentriert ist, verwenden Sie eine Ebenenliste als Hintergrund Ihrer Symbolleiste, anstatt ein Bild als Ansicht zu verwenden.

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>

Dies sollte ein zentriertes Logo mit einer bestimmten Hintergrundfarbe gewährleisten.

32
Blueberry

Dies ist nicht die beste Lösung, aber es ist eine Umgehung, die auch dann funktioniert, wenn Sie eine Taste oder einen Menüpunkt haben.

versuchen

<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

Ich hatte ein ähnliches Problem. Ich habe versucht, den Layer-Listen-Ansatz zu verwenden, den Blueberry vorgeschlagen hat. Sobald ich jedoch ein hochauflösendes Asset für das Logo eingesetzt habe, funktionierte die Lösung nicht mehr. Eine Bitmap in einer Ebenenliste hat einen Fehler: Sie vergrößert kleinere Bilder, um sie an den Raum anzupassen, verkleinert jedoch nicht. Solange Sie mit der Verwendung winziger Bilder, die bei Vergrößerung körnig/pixelig aussehen, in Ordnung sind, funktioniert die Ebenenliste einwandfrei.

Um dieses Problem zu lösen und ein zentriertes, hochauflösendes Logo zu haben, entfernte ich das Android:background-Attribut vollständig aus der Toolbar, fügte Android:background="?attr/colorPrimary" zu meinem AppBarLayout-übergeordneten Element hinzu und fügte diesen schrecklichen Code in die onCreate-Methode meiner Aktivität ein:

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

Dazu erstellen Sie eine Leinwand in der Größe der Symbolleiste und eine durch das Verhältnis skalierte Version des Logos, zeichnen das neu skalierte Logo auf die Leinwand in der Mitte und setzen schließlich die Bitmap als Hintergrund der Aktionsleiste.

Auf der positiven Seite haben Sie mit diesem Ansatz die vollständige Kontrolle über Platzierung, Größenanpassung usw. Sie sind nicht auf die Möglichkeiten von XML beschränkt. Es ist schrecklich, da es ziemlich regelmäßig aufgerufen wird, wenn sich das Layout der Symbolleiste ändert, was Auswirkungen auf die Leistung hat. Wenn Sie jedoch von Ihrem Designteam gefordert werden (es geht nicht darum, was als erstes mit Material Design zu tun hat), ein Hintergrundlogo zu haben und fünf Stunden damit zu verbringen, nach der oben genannten Lösung zu suchen, ist die Leistung nicht mehr wichtig - Sie möchten nur, dass das verdammte Ding funktioniert. Der obige Code stinkt ziemlich nach Verzweiflung.

Ich lasse jemanden, der in der Android-Entwicklung fähiger ist, darauf aufmerksam machen, dass "Ich mache es falsch" und behebe mit dem obigen Code alle Leistungsprobleme/Fehler. Es ändert nichts an der Tatsache, dass das Layer-Listen-Bitmap beschädigt ist. Dies ist ein Hack (der nicht existieren sollte), um einen dummen Fehler (der auch nicht existieren sollte) in Android zu beheben.

2
maddog

Wenn der Benutzer eingestellt hat:

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

und danach etwas tun 

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

das Bild in der Symbolleiste wird dann nicht zentriert, da der Home-Button etwas Platz vom Layout beansprucht.
1.Erstellen Sie 9-Patch-PNGs aus Ihrer ursprünglichen .png-Ressource.
2.Eine Zeichnung aus 9-Patches mit XML erstellen, wobei die Layer-Liste als Beispiel für toolbar_background.xml verwendet wird:

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


.__ Stellen Sie dann die Toolbar_background-Ressource als Hintergrund im Toolbar-Element ein:

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


Das ist alles.

1
artyom mamaev

Wenn Sie ein komplizierteres Layout in der Symbolleiste als nur ein Bild zentrieren müssen, platziere ich dies in onCreate () meiner Aktivität: 

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

Wenn onLayoutChange aufgerufen wird, ist die Breite Ihres Layouts bereits festgelegt, sodass Sie es einfach in die Mitte schieben.

HINWEIS: Es ist wichtig, die Symbolleiste nur zu zentrieren (siehe if-Bedingung), wenn sie nicht zentriert ist. Andernfalls wird dieser Callback in einer Endlosschleife erneut aufgerufen.

Die XML-Datei sieht folgendermaßen aus:

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

Ich mag die Herangehensweise von Ruben Yoo's Antwort wegen seiner Einfachheit . Es ist explizit, einfach zu folgen und hält alle Codeänderungen zusammen.

Hier ist eine aktualisierte Version mit einigen kleineren Verbesserungen:

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

Änderungen:

  1. AppBarLayout Eltern eingeführt 
  2. explizite Größe ?attr/actionBarSize wird für Rahmen und Symbolleiste bereitgestellt
  3. ImageView stimmt in Breite und Höhe mit den übergeordneten Abmessungen überein
  4. logo in centerInside geändert
0

sie können diesen Code verwenden:

     <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