网上关于toolbar的教程有很多,很多新手,在使用toolbar的时候踩坑实在太多了,不好好总结一下,实在浪费。如果你想学习toolbar,你肯定会去去搜索androd toolbar,既然你能看到这篇文章,说明还是搜了xamarin android toolbar。那么这篇文章就好好总结一下toolbar在xamarin android中如何使用,减少大家踩坑的时间。
了解Toolbar
android3.0推了ActionBar这个控件,android5.0开始推出Materal Design,其中就有ToolBar控件。可能官方觉得ActionBar限制app开发设计的弹性,google非常推荐大家使用ToolBar来作为客户端的导航栏,以此来取代ActionBar。
ToolBar使用更灵活,设计更多样性。主要的优点有1.可以设置导航栏图标、Logo、标题和子标题等属性; 2可添加自定义控件;3.支持Action Menu;4.可随意设置位置
xamarin android中使用Toolbar
官方为了将toolbar这一控件向下兼容,推出了兼容版的toolbar,所以首先的引入Android.Support.V7.AppCompat。我们先来看看最终完成的整体的效果图
-
<?xml version= "1.0" encoding= "utf-8"?>
-
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
-
xmlns:app= "http://schemas.android.com/apk/res-auto"
-
android:orientation= "vertical"
-
android:layout_width= "match_parent"
-
android:layout_height= "match_parent"
-
android:background= "@color/color_white"
-
android:fitsSystemWindows= "true">
-
<android.support.v7.widget.Toolbar
-
android:id= "@+id/toolbar"
-
android:layout_width= "match_parent"
-
android:layout_height= "60dp"
-
android:background= "@color/color_primary"
-
android:navigationIcon= "@drawable/icon2"
-
android:logo= "@drawable/icon"
-
android:subtitle= "子标题"
-
android:title= "标题"
-
android:titleTextColor= "@color/color_white">
-
<TextView
-
android:layout_width= "wrap_content"
-
android:layout_height= "wrap_content"
-
android:text= "自定义文本">
-
</TextView>
-
</android.support.v7.widget.Toolbar>
-
</LinearLayout>
-
<style name="AppTheme" parent="AppTheme.Base">
-
</style>
-
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
-
</style>
往下看怎么解决。
坑1:设置Toolbar属性不能使用android:**** 而使用app:*****
我们没有看到这些设置的属性很正常,我们使用android:*** 找不到的属性,应该使用Toolbar这个控件自带的属性。所以我在根布局加了
xmlns:app="http://schemas.android.com/apk/rs-auto" 使用app:***来设置属性如下
-
<android.support.v7.widget.Toolbar
-
android:id= "@+id/toolbar"
-
android:layout_width= "match_parent"
-
android:layout_height= "60dp"
-
android:background= "@color/color_primary"
-
android:navigationIcon= "@drawable/icon2"
-
android:logo= "@drawable/icon"
-
android:subtitle= "子标题"
-
android:title= "标题"
-
android:titleTextColor= "@color/color_white">
toolbar可以添加菜单项,在Resources文件下建一个menu文件夹专门放菜单。先来看一下actionMenu.xml 菜单项文件,然后在代码实现方法。
-
"1.0" encoding="utf-8" xml version=
-
<menu xmlns:android="http://schemas.android.com/apk/res/android"
-
xmlns:app= "http://schemas.android.com/apk/res-auto">
-
<item android:id="@id/menu_edit"
-
android:icon= "@drawable/edit"
-
android:title= "编辑"
-
app:showAsAction= "ifRoom"/>
-
<item android:id="@id/menu_search"
-
android:icon= "@drawable/search"
-
android:title= "搜索"
-
app:showAsAction= "ifRoom"/>
-
<item android:id="@id/menu_add"
-
android:icon= "@drawable/add"
-
android:title= "添加"
-
app:showAsAction= "ifRoom"/>
-
</menu>
-
using Android.App;
-
using Android.Views;
-
using Android.Widget;
-
using Android.OS;
-
using Android.Support.V7.App;
-
namespace ToolbarDemo
-
{
-
[]
-
public class MainActivity : AppCompatActivity
-
{
-
protected override void OnCreate(Bundle bundle)
-
{
-
base.OnCreate(bundle);
-
SetContentView(Resource.Layout.Main);
-
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
-
toolbar.InflateMenu(Resource.Menu.actionMenu); //填充actionMenu菜单项
-
toolbar.MenuItemClick += (s, e) => //菜单项单击事件
-
{
-
switch (e.Item.ItemId)
-
{
-
case Resource.Id.menu_add:
-
Toast.MakeText( this, "添加菜单项", ToastLength.Short).Show();
-
break;
-
case Resource.Id.menu_edit:
-
Toast.MakeText( this, "编辑菜单项", ToastLength.Short).Show();
-
break;
-
case Resource.Id.menu_search:
-
Toast.MakeText( this, "搜索菜单项", ToastLength.Short).Show();
-
break;
-
}
-
};
-
}
-
public override bool OnCreateOptionsMenu(IMenu menu)
-
{
-
return base.OnCreateOptionsMenu(menu);
-
}
-
}
-
}
关于showAsAction 展现在Action条目中的几个属性值有这几个:
- always:使菜单项一直显示在ToolBar上。
- ifRoom:如果有足够的空间,这个值会使菜单项显示在ToolBar上。
- never:使菜单项永远都不出现在ToolBar上,在…的子项中显示。
- withText:使菜单项和它的图标,菜单文本一起显示。
坑2:toolbar中使用setSupportActionBar方法菜单项不见了
如果在onCreate方法里面使用兼容包的方法SetSupportActionBar(toolbar) 后发现菜单项不显示了,这就有点尴尬了,所以要在OnCreateOptionsMenu方法中加上一句代码加载菜单项才能显示
-
public override bool OnCreateOptionsMenu(IMenu menu)
-
{
-
MenuInflater.Inflate(Resource.Menu.actionMenu,menu);
-
return base.OnCreateOptionsMenu(menu);
-
}
toolbar中设置菜单项图标颜色、自定义菜单图标、设置菜单项文字颜色
对于设置各种颜色,我们先来看看这张图,我是盗图的......,然后结合style文件看看如何设置这些颜色。原文地址http://blog.csdn.net/u012702547/article/details/50932090
-
<style name="AppTheme.NoActionBar">
-
<!--状态栏颜色-->
-
<item name="colorPrimaryDark">@color/colorPrimaryDark </item>
-
<!--控制各个控件被选中时的颜色-->
-
<item name="colorAccent">@color/colorAccent </item>
-
<!--页面背景色-->
-
<item name="android:windowBackground">@color/windowBackg </item>
-
<!--底部导航栏颜色-->
-
<item name="android:navigationBarColor">@color/navigationColor </item>
-
<!--Appbar背景色-->
-
<item name="android:colorPrimary">@color/colorPrimary </item>
-
<!--ToolBar上的Title颜色-->
-
<item name="android:textColorPrimary">@color/textColorPrimary </item>
-
<!--各个控制控件的默认颜色-->
-
<item name="android:colorControlNormal">@color/colorControlNormal </item>
-
</style>
设置菜单项图标颜色:
通过上面的图和代码已经知道android:colorControlNormal设置各种控件的默认颜色,在Activity中Theme中这样写就可以了:
-
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
-
<item name="colorControlNormal">@color/color_white </item>
-
</style>
为什么要在Activity的主题里面设置?能不能直接Toolbar的主题设置,当然可以,直接通过设置Toolbar控件的android:theme=“****”就可以了。主题样式如下
-
<style name="ActionMenuTheme" parent="Theme.AppCompat.Light.NoActionBar">
-
<item name="colorControlNormal">@color/color_white </item>
-
<!--改变菜单项文字颜色-->
-
<item name="android:textColorPrimary">@color/color_red </item>
-
<item name="android:textSize">12sp </item>
-
</style>
上面的toolbar的主题ActionMenuTheme 中的<item name="adnroid:textColorPrimary">@color/color_red</item>就是这事菜单项文字的颜色。效果如下:
toolbar 溢出菜单项图标的设置
如果你觉tollbar 的溢出菜单三个点不符合的审美感觉,你可以可以自定义一个图标来修改,同样我们设置toolbar的android:theme来做这件事情
-
<style name="ActionMenuTheme" parent="Theme.AppCompat.Light.NoActionBar">
-
<item name="colorControlNormal">@color/color_white </item>
-
<!--改变菜单项文字颜色-->
-
<item name="android:textColorPrimary">@color/color_red </item>
-
<item name="android:textSize">12sp </item>
-
<!--设置溢出菜单项图标-->
-
<item name="actionOverflowButtonStyle">@style/ActionButton.Overflow.Custom </item>
-
</style>
-
<style name="ActionButton.Overflow.Custom" parent="android:style/Widget.Holo.Light.ActionButton.Overflow">
-
<item name="android:src">@drawable/add_white </item>
-
</style>
toolbar自定义溢出菜单样式
虽然上面我们进行了图标颜色,自定义图标,菜单文字颜色的修改,但是这和我们一般的app上的ToolBar还是有一定差距,菜单项挡住了toolbar,正常的做法应该往下移才合理一点。如图所示:
添加以下样式
-
<!--溢出菜单项下移-->
-
<style name="OverflowMenuStyle" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
-
<!-- 是否覆盖锚点,默认为true,即盖住Toolbar -->
-
<item name="overlapAnchor">false </item>
-
<!-- 弹出层背景颜色 -->
-
<item name="android:popupBackground">@color/color_primary </item>
-
<!-- 弹出层垂直方向上的偏移,即在竖直方向上距离Toolbar的距离,值为负则会盖住Toolbar -->
-
<item name="android:dropDownVerticalOffset">10dp </item>
-
<!-- 弹出层水平方向上的偏移,即距离屏幕左边的距离,负值会导致右边出现空隙 -->
-
<item name="android:dropDownHorizontalOffset">-10dp </item>
-
</style>
-
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
-
<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle </item>
-
<item name="actionOverflowButtonStyle">@style/ActionButton.Overflow.Custom </item>
-
<item name="android:textColorPrimary">@color/color_white </item>
-
<item name="android:textSize">15sp </item>
-
</style>
坑3:无法再Toolbar中设置app:popopTheme自定义溢出菜单样式
看了android的做法这个溢出菜单下移OverflowMenuStyle样式可以写在Toolbar 的属性app:popupTheme但是没有效果,如果知道怎么解决,欢迎评论指出。
坑4:toolbar菜单项无法同时显示图标和文字
根据图上所看到的,显示toolbar上的菜单项是图标,但是显示popupMenu上的只有文字没有图标,我们想要修改一下让图标和文字同时显示在popupMenu上该怎么做呢。使用withText也并有作用,这时要使用app:actionLayout属性了。在menu文件夹的菜单布局下加上app:actionLayout属性
- <code class="language-html"><?xml version="1.0" encoding="utf-8" ?>
- <menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto">
- <item android:id="@+id/menu_edit"
- android:icon="@drawable/edit"
- android:title="编辑"
- app:actionLayout="@layout/menu_action_edit"
- app:showAsAction="withText"/>
- <item android:id="@+id/menu_search"
- android:icon="@drawable/search"
- android:title="搜索"
- app:showAsAction="always|withText"/>
- <item android:id="@+id/menu_add"
- android:icon="@drawable/add_small"
- android:title="添加"
- app:showAsAction="always|withText"
- app:actionLayout="@layout/menu_action_add"
- />
- </menu></code>
-
"1.0" encoding="utf-8" xml version=
-
<menu xmlns:android="http://schemas.android.com/apk/res/android"
-
xmlns:app= "http://schemas.android.com/apk/res-auto">
-
<item android:id="@+id/menu_edit"
-
android:icon= "@drawable/edit"
-
android:title= "编辑"
-
app:actionLayout= "@layout/menu_action_edit"
-
app:showAsAction= "withText"/>
-
<item android:id="@+id/menu_search"
-
android:icon= "@drawable/search"
-
android:title= "搜索"
-
app:showAsAction= "always|withText"/>
-
<item android:id="@+id/menu_add"
-
android:icon= "@drawable/add_small"
-
android:title= "添加"
-
app:showAsAction= "always|withText"
-
app:actionLayout= "@layout/menu_action_add"
-
/>
-
</menu>
-
"1.0" encoding="utf-8" xml version=
-
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-
android:layout_width= "wrap_content"
-
android:layout_height= "wrap_content"
-
android:paddingLeft= "10dip"
-
android:paddingRight= "10dip"
-
android:gravity= "center"
-
android:text= "添加"
-
android:drawableLeft= "@drawable/add_white"
-
android:textColor= "@color/color_white"
-
android:clickable= "true" />
overflow中的ActionMenu显不显示图标,是有MenuBuilder这个类的setOptionalIconsVisable方法决定的,在菜单展开的时候给这个方法传入true,那每个菜单项的图标和文字都会显示出来,尴尬的是要java的反射方法去做这件事,重写OnMenuOpend方法
-
public override bool OnMenuOpened(int featureId, IMenu menu)
-
{
-
System.Diagnostics.Debug.WriteLine(featureId);
-
if ( menu != null)
-
{
-
var javaObj = (Java.Lang.Object)menu;
-
var javaClass = javaObj.Class;
-
if (javaClass.SimpleName.EndsWith( "MenuBuilder"))
-
{
-
try {
-
Java.Lang.Reflect.Method m = javaClass.GetDeclaredMethod( "setOptionalIconsVisible", new Java.Lang.Class[] { Java.Lang.Boolean.Type });
-
m.Accessible = true;
-
m.Invoke(javaObj, new Java.Lang.Object[] { true});
-
}
-
catch (Java.Lang.NoSuchFieldException e)
-
{
-
System.Console.WriteLine( "onMenuOpened:{0}",e.ToString());
-
}
-
}
-
}
-
return base.OnMenuOpened(featureId, menu);
-
}
最后总结一句:纸上得来终觉浅,绝知此事要躬行。关于toolbar的更多属性还要仔细去琢磨。
代码下载地址http://download.csdn.net/detail/kebi007/9835823