Android自定义工具栏(二)——试试Toolbar

接上篇,上篇提到要实现下面这个样子的工具栏:


主要是两个改动:一是把三个小圆点换成三个小方点,还有就是把弹出菜单的位置改到下面。

既然需要用到Toolbar这个组件,首先先在layout里加上下面这段:

    <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="@dimen/toolbar_height"
                                       android:background="@color/colorBackground"
                                       app:contentInsetStart="0dp">
        <TextView
                android:id="@+id/toolbar_text"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/colorWhite"
                android:textSize="20sp"
                android:text="Hit me"/>
    </android.support.v7.widget.Toolbar>

然后在onCreate()里调用一个initToolbar()方法:

    private void initToolbar() {
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        // set toolbar title as empty
        toolbar.setTitle("");
        // set toolbar
        setSupportActionBar(toolbar);
        // set menu icon
        Drawable menuIcon = zoomDrawable(getDrawable(R.drawable.menu),
                getResources().getDimension(R.dimen.toolbar_menu_icon_width),
                getResources().getDimension(R.dimen.toolbar_menu_icon_height));
        toolbar.setOverflowIcon(menuIcon);
        // set back navigation icon and click listener
        Drawable navigationIcon = zoomDrawable(getDrawable(R.drawable.back_arrow),
                                getResources().getDimension(R.dimen.toolbar_navi_icon_width),
                                getResources().getDimension(R.dimen.toolbar_navi_icon_height));
        toolbar.setNavigationIcon(navigationIcon);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        // set toolbar text click listener
        TextView text = (TextView) findViewById(R.id.toolbar_text);
        text.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), "Hit me!", Toast.LENGTH_SHORT).show();
            }
        });
    }

首先找到Toolbar这个view,然后通过setSupportActionBar()设置生效。

Toolbar确实比ActionBar灵活很多,可以通过setOverflowIcon()设置overflow菜单的图案,也可以通过setNavigationIcon()方法设置回退按钮的图案,还有回退按钮点击后的响应。但是发现一个问题,UX给的overflow菜单的图片太大了,显示出来非常难看,但是又没有办法配置viewsize,最后没办法只能自己写个位图缩放的方法来解决这个问题了。。。

    private Drawable zoomDrawable(Drawable drawable, float w, float h) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap oldBmp = drawableToBitmap(drawable);
        Matrix matrix = new Matrix();
        float scaleWidth = (w / width);
        float scaleHeight = (h / height);
        matrix.postScale(scaleWidth, scaleHeight);
        Bitmap newBmp = Bitmap.createBitmap(oldBmp, 0, 0, width, height,
                matrix, true);
        return new BitmapDrawable(null, newBmp);
    }

    private Bitmap drawableToBitmap(Drawable drawable) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE
                ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
        Bitmap bitmap = Bitmap.createBitmap(width, height, config);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }

下面再看一看修改弹出菜单位置的问题,这个可以通过修改res/values/style.xml实现:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="actionOverflowMenuStyle">@style/overflowMenuStyle</item>
    </style>

    <style name="overflowMenuStyle" parent="@style/Widget.AppCompat.Light.PopupMenu.Overflow">
        <item name="android:overlapAnchor">false</item>
        <item name="android:dropDownWidth">wrap_content</item>
        <item name="android:dropDownVerticalOffset">18dp</item>
        <item name="android:dropDownHorizontalOffset">-10dp</item>
    </style>
</resources>

首先写一个自定义的overflowMenuStyle,继承自Widget.AppCompat.Light.PopupMenu.Overflow。然后调整一下下面4个配置:

  • android:overlapAnchor: 是否和锚点重叠,也就是那三个小圆点
  • android:dropDownWidth: 菜单的宽度,这里用了warp_content
  • android:dropDownVerticalOffset: 弹出菜单在垂直方向上的偏移
  • android:dropDownHorizontalOffset: 弹出菜单在水平方向上的偏移(负值表示向左偏移)

最后在你的AppTheme里把actionOverflowMenuStyle配成这个样式就可以了。

到这里似乎完美解决了问题,但是我在想万一以后UX又有什么新需求呢?比如说,做成下面这个样子:


当我们把回退按钮隐藏掉以后,会发现左边一直会有16dp的空隙,怎么去掉这个空隙呢?查了一下Toolbar的配置,找到一个contentInsetStart的属性,默认是16dp,因此需要在xml里把Toolbar的这个属性配置为0dp

除此以外,如果需要把那三个小方点的位置往左挪一点呢?如果要修改弹出菜单的样式怎么办?看起来又搞不定了,还是得找到一个一劳永逸、以不变应万变的方法呀,干脆自己封装一个toolbar好了,参见下篇。

示例代码下载

猜你喜欢

转载自blog.csdn.net/turkeycock/article/details/51837209