it-swarm.com.ru

Изображение панели инструментов по центру

Используя последний Android.support.v7.widget.Toolbar, я хочу центрировать изображение на панели инструментов, но оно остается слева.

Лучший способ для меня - использовать метод toolbar.setLogo() и центрировать логотип, но я не вижу способа сделать это.

Я использую макет для 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>

Есть ли возможность добавить изображение (логотип) на панель инструментов и отцентрировать его? Программно или в макете?

56
Nicolas Oz

Панель инструментов это просто ViewGroup, вы можете настроить столько, сколько хотите.

Попробуй это : 

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

Это должно привести ваш imageView в центр панели инструментов.

117
Abhinav Puri

Если у вас есть какие-либо виды и вы не можете выровнять логотип по центру, это произойдет потому, что центрирование основано на оставшемся пространстве, а не на всей панели инструментов.

Чтобы гарантировать центрирование логотипа, попробуйте использовать список слоев в качестве фона панели инструментов вместо того, чтобы использовать изображение в качестве вида.

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>

Это должно обеспечить центрированный логотип с определенным цветом фона.

32
Blueberry

Это не лучшее решение, но это обходной путь, который работает, даже если у вас есть кнопка вверх или пункт меню.

пытаться

<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

У меня была похожая проблема. Я попытался использовать подход со списком слоев, который предложил Blueberry, но как только я добавил актив логотипа в высоком разрешении, решение больше не работало. У растрового изображения в списке слоев есть ошибка: он увеличит меньшие изображения, чтобы соответствовать пространству, но не уменьшит большие изображения. Таким образом, пока вы в порядке с использованием крошечных изображений, которые выглядят зернистыми/неровными при увеличении, список слоев работает нормально.

Чтобы решить эту проблему и получить центрированный логотип с высоким разрешением, я полностью удалил атрибут Android:background с панели инструментов, добавил Android:background="?attr/colorPrimary" к моему родителю AppBarLayout, а затем бросил этот ужасный код в метод onCreate своей деятельности:

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

Он работает путем создания холста размером с панель инструментов и масштабируемой по соотношению версии логотипа, рисования нового логотипа с измененным размером на холсте в центре и, наконец, установки растрового изображения в качестве фона панели действий.

С другой стороны, этот подход дает вам полный контроль над размещением, изменением размеров и т.д. Не ограничивается тем, что вы можете делать в XML. Это ужасно, потому что он вызывается довольно регулярно, когда меняется макет панели инструментов, что означает, что это влияет на производительность. Но когда ваша команда дизайнеров (которая заботится не только о материальном дизайне) требует от вас иметь фоновый логотип и тратить пять часов на поиски решения выше, производительность перестает иметь значение - вы просто хотите, чтобы эта чертова штука сработала. Приведенный выше код довольно сильно пахнет отчаянием.

Я позволю кому-то более способному, чем я, в разработке Android указать, что «я делаю это неправильно», и исправлю любые проблемы с производительностью/ошибки, которые есть в приведенном выше коде. Это не меняет того факта, что растровое изображение списка слоев повреждено, и это хак (который не должен существовать) для исправления глупой ошибки (которая также не должна существовать) в Android.

2
maddog

Если пользователь установил:

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

а после сделать что-то вроде 

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

тогда изображение внутри панели инструментов также не будет центрировано, потому что кнопка «домой» съедает некоторое пространство из макета. Горизонтальный центр изображения будет смещен по ширине иконки дома. Так что лучшее решение:
1.Создайте 9-patch png из вашего исходного изображения .png ресурса.
2.Создайте отрисовку из 9-патча с xml, используя список слоев в качестве примера 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>


Затем установите ресурс toolbar_background в качестве фона в элементе панели инструментов:

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


Это все.

1
artyom mamaev

Если вам нужно центрировать более сложный макет на панели инструментов, а не просто изображение, это то, что я поместил в свою активность onCreate ()

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

Когда вызывается onLayoutChange , ширина вашего макета уже определена, поэтому вы просто перемещаете ее в центр.

ПРИМЕЧАНИЕ: Важно только центрировать панель инструментов (см. Условие if), когда она не центрирована, в противном случае этот обратный вызов будет повторно вызван в бесконечном цикле.

Файл XML будет выглядеть так:

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

Мне нравится подход, который дает ответ Рубена Ю из-за его простоты . Он явный, простой в использовании и сохраняет все изменения кода вместе.

Вот обновленная версия с некоторыми незначительными улучшениями:

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

Изменения:

  1. представил AppBarLayout родитель 
  2. явный размер ?attr/actionBarSize для фрейма и панели инструментов
  3. ImageView соответствует родительским размерам по ширине и высоте
  4. логотип изменен до centerInside
0
Richard Le Mesurier

вы можете использовать этот код:

     <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