概述
本部分介绍如何在 Android 5.0 Lollipop 之前的 Android 版本上使用 Toolbar。 如果应用不支持早于 Android 5.0 的 Android 版本,则可以跳过本部分。
由于 Toolbar 是 Android v7 支持库的一部分,因此可以在运行 Android 2.1(API 级别 7)及更高级别的设备上使用它。 但是,必须安装 Android 支持库 v7 AppCompat NuGet 并修改代码,以便它使用此库中提供的 Toolbar 实现。 本部分介绍如何安装此 NuGet,并从“添加第二个工具栏”修改 ToolbarFun 应用,使其在低于 Lollipop 5.0 的 Android 版本上运行。
修改应用以使用工具栏的 AppCompat 版本:
为应用设置最低版本和目标 Android 版本。
安装 AppCompat NuGet 包。
使用 AppCompat 主题而不是内置的 Android 主题。
修改
MainActivity,使其子类为AppCompatActivity而不是Activity。
以下各节详细介绍了上述每个步骤。
设置最低版本和目标 Android 版本
应用的目标框架必须设置为 API 级别 21 或更高版本,否则应用将无法正确部署。 如果在部署应用时看到“包 “tileModeX”中找不到属性“tileModeX”的资源标识符”,这是因为目标框架未设置为 Android 5.0(API 级别 21 - Lollipop) 或更高版本。
将目标框架级别设置为 API 级别 21 或更高版本,并将 Android API 级别项目设置设置为应用支持的最低 Android 版本。 有关设置 Android API 级别的详细信息,请参阅了解 Android API 级别。
在 ToolbarFun 示例中,最低 Android 版本设置为 KitKat(API 级别 4.4)。
安装 AppCompat NuGet 包
接下来,将 Android 支持库 v7 AppCompat 包添加到项目中。 在 Visual Studio 中,右键单击“引用”并选择“管理 NuGet 包...”。单击“浏览”并搜索“Android 支持库 v7 AppCompat”。 选择 Xamarin.Android.Support.v7.AppCompat 并单击 安装:
安装此 NuGet 后,如果其他几个 NuGet 软件包尚未安装,也会同时安装(例如 Xamarin.Android.Support.Animated.Vector.Drawable、 Xamarin.Android.Support.v4,以及 Xamarin.Android.Support.Vector.Drawable)。 有关安装 NuGet 包的详细信息,请参阅演练:在项目中包括 NuGet。
使用 AppCompat 主题和工具栏
AppCompat 库附带了多个 Theme.AppCompat 主题,这些主题可用于 AppCompat 库支持的任何 Android 版本。 ToolbarFun 示例应用主题派生自 Theme.Material.Light.DarkActionBar,该主题在低于 Lollipop 的 Android 版本中不可用。 因此,ToolbarFun 必须对该主题的 AppCompat 对应程序进行调整,以使用 Theme.AppCompat.Light.DarkActionBar。 此外,由于 Toolbar 在低于 Lollipop 的 Android 版本中不可用,因此必须使用 Toolbar 的 AppCompat 版本。 因此,布局必须使用 android.support.v7.widget.Toolbar 而不是 Toolbar。
更新布局
编辑 Resources/layout/Main.axml,并将 Toolbar 元素替换为以下 XML:
<android.support.v7.widget.Toolbar
android:id="@+id/edit_toolbar"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorAccent"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
编辑 Resources/layout/toolbar.xml,并将其内容替换为以下 XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
请注意,?attr 值不再带有 android: 前缀(回想一下,? 表示法引用当前主题中的资源)。 如果此处仍使用 ?android:attr,Android 将从当前正在运行的平台而不是 AppCompat 库引用属性值。 由于此示例使用 AppCompat 库定义的 actionBarSize,因此会删除 android: 前缀。 同样,@android:style 更改为 @style,以便 android:theme 属性设置为 AppCompat 库中的主题,此处会使用 ThemeOverlay.AppCompat.Dark.ActionBar 主题,而不是 ThemeOverlay.Material.Dark.ActionBar。
更新样式
编辑 资源/值/styles.xml,并将其内容替换为以下 XML:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme" parent="MyTheme.Base"> </style>
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="colorPrimary">#5A8622</item>
<item name="colorAccent">#A88F2D</item>
</style>
</resources>
此示例中的项名称和父主题不再带有 android: 前缀,因为我们使用的是 AppCompat 库。
此外,父主题更改为 Light.DarkActionBar 的 AppCompat 版本。
更新菜单
为了支持早期版本的 Android,AppCompat 库使用会镜像 android: 命名空间属性的自定义属性。 但是,某些属性(如 <menu> 标记中使用的 showAsAction 属性)在较旧的设备上不存在,showAsAction 是在 Android API 11 中引入的,但在 Android API 7 中不可用。 因此,必须使用自定义命名空间来为支持库定义的所有属性添加前缀。 在菜单资源文件中,定义了名为 local 的命名空间,用于为 showAsAction 属性添加前缀。
编辑 资源/菜单/top_menus.xml,并将其内容替换为以下 XML:
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_edit"
android:icon="@mipmap/ic_action_content_create"
local:showAsAction="ifRoom"
android:title="Edit" />
<item
android:id="@+id/menu_save"
android:icon="@mipmap/ic_action_content_save"
local:showAsAction="ifRoom"
android:title="Save" />
<item
android:id="@+id/menu_preferences"
local:showAsAction="never"
android:title="Preferences" />
</menu>
local 命名空间随以下行一起添加:
xmlns:local="http://schemas.android.com/apk/res-auto">
showAsAction 属性以此 local: 命名空间开头,而不是 android:
local:showAsAction="ifRoom"
同样,编辑 资源/菜单/edit_menus.xml,并将其内容替换为以下 XML:
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_cut"
android:icon="@mipmap/ic_menu_cut_holo_dark"
local:showAsAction="ifRoom"
android:title="Cut" />
<item
android:id="@+id/menu_copy"
android:icon="@mipmap/ic_menu_copy_holo_dark"
local:showAsAction="ifRoom"
android:title="Copy" />
<item
android:id="@+id/menu_paste"
android:icon="@mipmap/ic_menu_paste_holo_dark"
local:showAsAction="ifRoom"
android:title="Paste" />
</menu>
此命名空间开关如何为 API 级别 11 之前的 Android 版本上的 showAsAction 属性提供支持? 安装 AppCompat NuGet 时,自定义属性 showAsAction 及其所有可能的值包含在应用中。
子类 AppCompatActivity
转换的最后一步是修改 MainActivity,以使它成为 AppCompatActivity 的子类。 编辑 MainActivity.cs 并添加以下 using 语句:
using Android.Support.V7.App;
using Toolbar = Android.Support.V7.Widget.Toolbar;
这声明 Toolbar 为 AppCompat 版本的 Toolbar。 接下来,更改 MainActivity 的类定义:
public class MainActivity : AppCompatActivity
若要将操作栏设置为 AppCompat 版本的 Toolbar,请将调用 SetActionBar 替换为 SetSupportActionBar。 在此示例中,标题也作了更改,以表明使用的是 Toolbar 的 AppCompat 版本:
SetSupportActionBar (toolbar);
SupportActionBar.Title = "My AppCompat Toolbar";
最后,将最低 Android 级别更改为要支持的 Lollipop 前值(例如 API 19)。
生成应用并在预 Lollipop 设备或 Android 仿真器上运行它。 以下屏幕截图显示了运行 KitKat 的 Nexus 4 上的 ToolbarFun AppCompat 版本(API 19):
使用 AppCompat 库时,无需基于 AppCompat 库的 Android 版本切换主题,就可以在所有受支持的 Android 版本中提供一致的用户体验。

