【问题标题】:Android toolbar back arrow with icon like WhatsApp带有 WhatsApp 等图标的 Android 工具栏后退箭头
【发布时间】:2015-08-03 13:30:20
【问题描述】:

如何在 WhatsApp 等 android 工具栏中显示带有后退箭头的图标?

我使用下面的代码在工具栏中设置返回箭头和图标。

 toolbar = (Toolbar) findViewById(R.id.toolbar);
 setSupportActionBar(toolbar);
 getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 getSupportActionBar().setDisplayShowHomeEnabled(true);
 getSupportActionBar().setHomeButtonEnabled(true);
 toolbar.setLogo(icon);

但我得到的结果如下图。

我想紧跟在后退箭头之后的图标。我不希望后退箭头和图标之间有任何间隙,如下图 WhatsApp。

如何在 WhatsApp 等工具栏中设置带后退箭头的图标?

【问题讨论】:

  • 它不会回答,但就用户体验而言,合并背部和轮廓图像并不是一个好主意。如果您在图像右侧添加边距,您的结果似乎更合适
  • @HugoGresse 我不想将个人资料图片与后退箭头合并。我只想把它放在箭头旁边,没有任何边距或填充间隙。
  • 是的,但它会大大减少按钮的交互大小,它与材料指南相矛盾并降低可访问性

标签: android toolbar android-support-library android-appcompat


【解决方案1】:

据我所知, WhatsApp 未使用 App-compat 支持库工具栏Whatsapp 正在使用

设置自定义操作栏
actionBar.setCustomView(R.layout.conversation_actionbar);

附件是conversation_actionbar.xml,Whatsapp正在使用

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/custom_view"
android:layout_width="fill_parent"
android:layout_height="?actionBarSize"
android:clipChildren="false" >

<LinearLayout
    android:id="@id/back"
    style="@style/ActionBarButtonStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:contentDescription="@string/abc_action_bar_up_description"
    android:enabled="false"
    android:orientation="horizontal"
    android:padding="@dimen/abc_action_bar_default_padding_material" >

    <ImageView
        android:id="@id/up"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left|center"
        android:scaleType="center"
        android:src="?homeAsUpIndicator" />

    <FrameLayout
        android:id="@id/conversation_contact_photo_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left|center"
        android:layout_marginRight="0.0dip" >

        <ImageView
            android:id="@id/conversation_contact_photo"
            android:layout_width="35.0dip"
            android:layout_height="35.0dip"
            android:scaleType="fitCenter" />

        <View
            android:id="@id/transition_start"
            android:layout_width="35.0dip"
            android:layout_height="35.0dip" />

        <ProgressBar
            android:id="@id/change_photo_progress"
            style="?android:attr/progressBarStyleSmallInverse"
            android:layout_width="35.0dip"
            android:layout_height="35.0dip"
            android:layout_gravity="center"
            android:visibility="gone" />
    </FrameLayout>
</LinearLayout>

<LinearLayout
    android:id="@id/conversation_contact"
    style="@style/ActionBarButtonStyle"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_toRightOf="@id/back"
    android:clickable="true"
    android:clipChildren="false"
    android:orientation="vertical"
    android:paddingBottom="2.0dip"
    android:paddingLeft="4.0dip"
    android:paddingRight="0.0dip"
    android:paddingTop="0.0dip" >

    <com.whatsapp.TextEmojiLabel
        android:id="@id/conversation_contact_name"
        style="@style/Theme.ActionBar.TitleTextStyle.Condensed"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:ellipsize="end"
        android:gravity="left"
        android:lines="1"
        android:scrollHorizontally="true"
        android:singleLine="true" />

    <LinearLayout
        android:id="@id/conversation_contact_status_holder"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:clipChildren="false"
        android:clipToPadding="false"
        android:orientation="horizontal" >

        <TextView
            android:id="@id/conversation_contact_status_prefix"
            style="@style/Theme.ActionBar.SubtitleTextStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:lines="1"
            android:paddingRight="3.5sp"
            android:singleLine="true"
            android:text="@string/conversation_last_seen"
            android:visibility="gone" />

        <TextView
            android:id="@id/conversation_contact_status"
            style="@style/Theme.ActionBar.SubtitleTextStyle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="left"
            android:ellipsize="end"
            android:lines="1"
            android:singleLine="true" />

        <View
            android:layout_width="0.0dip"
            android:layout_height="1.0dip"
            android:layout_weight="1.0" />
    </LinearLayout>
</LinearLayout>

但我建议你遵循 Materail 设计规则并使用 App-compat Support Library 的 ToolBar

可以得到如下图所示的结果

使用以下代码

your_activity.xml:

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar_chats"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
            <include layout="@layout/toolbar_conversation"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>

toolbar_conversation.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_width="fill_parent"
android:layout_height="?actionBarSize"
>
<!-- android:background="?attr/selectableItemBackgroundBorderless" will cause this Custom View to make ripple effect -->

<LinearLayout
    android:id="@+id/conversation_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_centerVertical="true"
    android:contentDescription="@string/abc_action_bar_up_description"
    android:orientation="horizontal">

        <ImageView
            android:id="@+id/conversation_contact_photo"
            android:layout_width="35.0dip"
            android:layout_height="35.0dip"
            android:src="@drawable/icon"
            android:scaleType="fitCenter" />
</LinearLayout>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_toRightOf="@id/conversation_image"
    android:orientation="vertical"
    android:paddingBottom="2.0dip"
    android:paddingLeft="4.0dip"
    android:paddingRight="0.0dip"
    android:paddingTop="0.0dip" >


    <TextView
        android:id="@+id/action_bar_title_1"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_gravity="center_vertical"
        android:layout_marginLeft="6dp"
        android:layout_weight="0.6"
        android:ellipsize="end"
        android:gravity="center_vertical"
        android:maxLines="1"
        android:textSize="18sp"
        android:text="shanraisshan"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/action_bar_title_2"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginLeft="6dp"
        android:layout_weight="0.4"
        android:ellipsize="end"
        android:text="last seen 1 hour ago"
        android:maxLines="1"
        android:textSize="12sp" />


</LinearLayout>

Activity.java

final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_chats);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.e("Toolbar","Clicked");
    }
});

请稍等,Whatsapp 将来会转为 App-compat 支持库。

【讨论】:

  • 你能在应用自定义布局后告诉我吗?如何在运行时更改图像??
  • 箭头和图标之间有更多的空间。如何减少空间并在运行时更改图像??
【解决方案2】:

您可以通过创建包含箭头和图像图标的自定义Drawable 来实现此结果,然后将其添加到工具栏toolbar.setNavigationIcon(drawable),如下所示。

        setSupportActionBar(mBinding.toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        Drawable drawable = new Drawable() {
            @Override
            public void draw(Canvas canvas) {

                int width = canvas.getWidth();
                int height = canvas.getHeight();

                Bitmap bMap = CircularImageView.getCircularBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.beautiful_eyes_small));    
                canvas.drawBitmap(bMap,(width-(bMap.getWidth())), (height/2)-(bMap.getHeight()/2), null);

                Bitmap bMap2 = BitmapFactory.decodeResource(getResources(), R.drawable.ic_arrow_back);
                canvas.drawBitmap(bMap2,0, (height/2)-(bMap2.getHeight()/2), null);
            }

            @Override
            public void setAlpha(int i) {

            }

            @Override
            public void setColorFilter(ColorFilter colorFilter) {

            }

            @Override
            public int getOpacity() {
                return PixelFormat.TRANSLUCENT;
            }
        };
        mBinding.toolbar.setNavigationIcon(drawable);

【讨论】:

  • 找不到 CircularImageView 类。
【解决方案3】:
getSupportActionBar().setDisplayShowHomeEnabled(true);

随着

getSupportActionBar().setIcon(R.drawable.ic_launcher);

【讨论】:

  • 这对我不起作用。后退箭头和图标之间的边距仍然存在,
  • 是否有图片周围有透明部分,请确保图片尺寸如图所示?
【解决方案4】:

看来您需要设置三个与操作栏相关的值才能显示图标:

actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowHomeEnabled(true); actionBar.setIcon(R.drawable.ic_cast_dark);

我原以为setDisplayHomeAsUpEnabled' and 'setIcon 应该足够了,但似乎还不够。

我正在使用 android.support.v7.app.ActionBar

【讨论】:

    【解决方案5】:

    您可以使用以下代码设置主页图标的填充

    ((ImageView) findViewById(android.R.id.home)).setPadding(x, x, x, x);
    x = set your value.
    

    【讨论】:

    • 应用程序在使用此代码时崩溃。此行出现 NullPointerException。
    • @Priyank 你在为你的项目使用 app-compat 支持库吗?
    • 是的,我正在使用appcompat-v7-r22.2
    【解决方案6】:

    好吧,我认为您应该尝试在后退按钮图像中进行一些编辑,例如应用一些简洁性以减少图像宽度并使其透明。可能会有所帮助

    【讨论】:

      【解决方案7】:

      您不能使用工具栏中的正常后退箭头来执行此操作,因为它有一个 minWidth 56dp with scaleType center 你可以这样做:

      <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          android:id="@+id/toolbar"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="?attr/colorPrimary">
      
          <ImageButton
              android:id="@+id/ibCustomBack"
              android:layout_width="wrap_content"
              android:layout_height="match_parent"
              android:background="?attr/selectableItemBackground"
              android:src="@drawable/ab_back_mtrl_am_alpha" />
      
          <ImageView
              android:id="@+id/yourImage"
              android:layout_width="35dp"
              android:layout_height="35dp"
              android:src="@drawable/pb" />
      
      </android.support.v7.widget.Toolbar>
      

      并自行处理 ibCustomBack。

      【讨论】: