【问题标题】:Toolbar image centered工具栏图像居中
【发布时间】:2014-12-17 20:32:20
【问题描述】:

使用最后一个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>

是否有可能将图像(徽标)添加到工具栏并将其居中? 以编程方式还是在布局中?

【问题讨论】:

标签: android android-toolbar


【解决方案1】:

Toolbar 只是一个 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 置于工具栏的中心。

【讨论】:

  • 如何在语法上更改设置图标?请帮忙。
  • @AnandSavjani 我所做的是在 ImageView 上设置一个 ID,然后在我的 Activity 中为它分配一个 ImageView 变量。然后简单来说,toolbarID.SetImageResource(Resource.Drawable.logo);
  • 如我所见,工具栏正在扩展 ViewGroup,因此 android:layout_gravity 不是有效属性。也许我做错了什么,但它不起作用。
  • 我已将layout_width="match_parent" 属性添加到ImageView 并且它有效。
【解决方案2】:

如果您有任何视图并且无法将徽标完全居中,那将是因为居中是基于剩余空间,而不是整个工具栏。

为确保徽标居中,请尝试使用图层列表作为工具栏的背景,而不是尝试使用图像作为视图。

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>

这应确保徽标居中,并具有特定的背景颜色。

【讨论】:

  • 这是一个更好的答案
  • 你如何用drawable在这里调整大小?
  • 我注意到您对另一个问题发表了评论,所以我假设您还没有找到答案 - 如果您找不到其他解决方案,也许重新创建具有特定尺寸的图像是您的最佳选择。
  • 有什么方法可以调整bitmap 的大小,因为当我这样做时,它会使我尝试使用的图像在Toolbar 中变得非常大且无法使用...
【解决方案3】:

这不是最好的解决方案,但即使您有向上按钮或菜单项,它也是一种解决方法。

试试

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

【讨论】:

  • 不错的答案 - 简单易懂。我已经在 2018 年更新了它,增加了一些改进 in my own answer - 如果你想将这些更改复制到你的,我很乐意删除我的,因为它不再添加任何有用的东西。
【解决方案4】:

我喜欢Ruben Yoo's answer because of its simplicity 提供的方法。它是明确的、易于遵循的,并将所有代码更改保持在一起。

这是一个更新版本,有一些小的改进:

<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

【讨论】:

    【解决方案5】:

    我遇到了类似的问题。我尝试使用 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 中执行的任何操作。这很糟糕,因为每当工具栏布局发生变化时都会定期调用它,这意味着会影响性能。但是,当您的设计团队(并不关心 Material Design 的第一件事)要求您拥有一个背景徽标并浪费五个小时寻找上述解决方案时,性能就不再重要了 - 您只希望该死的东西能够工作。上面的代码充满了绝望的味道。

    我会让在 Android 开发方面比我更有能力的人指出“我做错了”并修复上述代码存在的任何性能问题/错误。它不会改变图层列表位图已损坏的事实,这是一个 hack(不应该存在)来修复 Android 中的愚蠢错误(也不应该存在)。

    【讨论】:

    • 在我看来,最好的方法是 XML 方法,使用多种尺寸的图像进行缩放。这是一种相当标准的android方法。不知道我是否遇到过同样的问题?
    • 设备有各种形状和大小,因此无法处理所有设备,除非您只想为徽标提供 200MB 二进制文件。
    • 我认为您应该担心的只是密度,其中您只需要处理六个。有关如何支持多密度的更多信息,请参阅此处。 developer.android.com/guide/practices/…
    • 或者我可以使用单个资源和上面的代码,因为层列表位图应该足够智能,可以拍摄高分辨率图像并将其缩小,注意图像比例。对不起,但我不会回去重温这个。原生移动应用程序开发应该更容易。这是对我时间的毫无意义的浪费。
    • 很公平:)。只是让您知道最佳实践,当然每个项目都不同。
    【解决方案6】:

    如果用户设置:

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

    然后做类似的事情

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

    然后工具栏中的图像也不会居中,因为主页按钮会占用布局中的一些空间。图像的水平中心将偏向于主页图标的宽度。所以最好的解决方案:
    1.从您的原始图像 .png 资源创建 9-patch png。
    2.使用层列表作为示例toolbar_background.xml,使用xml从9-patch创建drawable:

    <?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 元素处将 toolbar_background 资源设置为背景:

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


    就是这样。

    【讨论】:

      【解决方案7】:

      如果您需要在工具栏中将更复杂的布局居中而不只是图像,这就是我放置在我的 Activity 的 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>
      

      【讨论】:

        【解决方案8】:

        您可以使用此代码:

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

        【讨论】:

          猜你喜欢
          • 2011-04-20
          • 1970-01-01
          • 1970-01-01
          • 2017-06-16
          • 2016-03-06
          • 2016-08-18
          • 2016-02-20
          • 2023-03-28
          相关资源
          最近更新 更多