工具栏兼容性
概述
本部分介绍如何在 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 版本中提供一致的用户体验。