接上篇,上篇提到要实现下面这个样子的工具栏:
主要是两个改动:一是把三个小圆点换成三个小方点,还有就是把弹出菜单的位置改到下面。
既然需要用到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菜单的图片太大了,显示出来非常难看,但是又没有办法配置view的size,最后没办法只能自己写个位图缩放的方法来解决这个问题了。。。
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好了,参见下篇。