[译]:Xamarin.Android用户界面——工具栏兼容性
博客分类: 官方教程
返回索引目录
原文链接:Part 3 - Toolbar Compatibility
译文链接:Xamarin.Android用户界面——工具栏兼容性
Part 3 - Toolbar Compatibility
本节将介绍如何在Android 5.0 Lollipop之前的Android版本中使用工具栏。如果你的应用将不做对Android 5.0之前的Android版本支持,可以略过此部分。
因为工具栏是Android v7支持库的一部分,故可以利用它让工具栏运行在Android 2.1(API level 7)及更高版本的设备上。但是,你 必须安装Android Support Library v7 AppCompat包(可以通过nuget引用),然后修改代码,以便使用此库中提供的工具栏实现。本节将介绍如何安装此包并修改之前在第2部分中的ToolbarFun应用,以此让它可以运行在Android 5.0 Lollipop之前的版本上。
要利用AppCompat版本的工具栏,需要以下 几个步骤:
- 设置应用的最低和目标Android版本。
- 安装AppCompat的NuGet包。
- 使用AppCompat主题替换内置的Android主题。
- 修改MainActivity,让它继承子AppCompatActivity —— 替换原来的Activity。
这些步骤将在以下部分进行详细解释。
设置最小及目标Android版本
应用的目标框架必须设置为API Level 21或更高版本,否则应用将无法正确部署。如果在部署应用时,遇到如No resource identifier found for attribute 'tileModeX' in package 'android'的错误,则是因为目标框架没有设置为Android 5.0 (API Level 21 - Lollipop)或更高版本。
将目标框架级别设置为API Level 21或更高,并将项目的Android API level设置为应用所要支持的最低Android版本。关于更多Android API level的设置,详见:原文:Understanding Android API Levels。在我们的ToolbarFun示例中,最低Android版本设置为KitKat(API Level 4.4)。
安装AppComapt的NuGet包
下一步,就是将Android Support Library v7 AppCompat的包添加到项目中。在Visual Studio中,右键引用,然后选择管理NuGet包,点击浏览标签,并搜索Android Support Library 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包安装内容,见:Walkthrough: Including a NuGet in your project。
使用AppCompat的主题及工具栏
AppCompat库中包含几个Theme.AppCompat主题 —— 可以在AppCompat库支持的任何版本的Android上使用。ToolbarFun示例应用主题派生自Theme.Material.Light.DarkActionBar —— 它不可以再Lollipop之前的Android版本上使用。因此,ToolbarFun必须使用AppCompat中对应的主题(Theme.AppCompat.Light.DarkActionBar)来适配。另外,由于工具栏 在Lollipop之前的Android上也不可用,故也需要使用AppCompat中对应的工具栏替换。故,布局中必须使用android.support.v7.widget.Toolbar替换原来的工具栏
修改布局
修改Resources/layout/Main.axml文件,并使用以下内容替换Toolbar元素:
<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 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。
修改样式
修改Resources/values/styles.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:命名空间中的属性。但是,有些属性在旧版的Android框架中不存在,如<menu>
标记的showAsAction属性,它是在Android API 11中引入的,但在Android API 7中不可用。因此,必须利用支持库来自定义的命名空间为所有属性添加前缀。在菜单资源文件中,定义了名为 local的命名空间,以此为showAsAction属性定义前缀。
编辑Resources/menu/top_menus.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="@drawable/ic_action_content_create"
local:showAsAction="ifRoom"
android:title="Edit" />
<item
android:id="@+id/menu_save"
android:icon="@drawable/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"
与上面一样,编辑Resources/menu/edit_menus.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="@drawable/ic_menu_cut_holo_dark"
local:showAsAction="ifRoom"
android:title="Cut" />
<item
android:id="@+id/menu_copy"
android:icon="@drawable/ic_menu_copy_holo_dark"
local:showAsAction="ifRoom"
android:title="Copy" />
<item
android:id="@+id/menu_paste"
android:icon="@drawable/ic_menu_paste_holo_dark"
local:showAsAction="ifRoom"
android:title="Paste" />
</menu>
而关于它如何在API Level 11时切换命名空间来提供ShowAsAction支持,其实现都包含在AppCompat的Nuget包中 —— 包括自定义的showAsAction属性以及所有可能的值。
修改父类为AppCompatActivity
切换的最后一步就是修改MainActivity,让它成为AppCompactActivity的子类。编辑MainActivity.cs,并添加以下引用:
using Android.Support.V7.App;
using Toolbar = Android.Support.V7.Widget.Toolbar;
这样就可以将Toolbar声明为AppCompat版本的Toolbar。然后 ,修改MainActivity的类定义:
public class MainActivity : AppCompatActivity
要使用AppCompat版本的工具栏,还需要使用SetSupportActionBar替换SetActionBar的调用。在此示例中,我们也将标题修改,以此 表示我们正在 使用的AppCompat版本的工具栏:
SetSupportActionBar (toolbar);
SupportActionBar.Title = "My AppCompat Toolbar";
最后,将最低Android基本更为要支持的版本(Lolipop之前的版本,如API 19)。
生成并运行 —— 在Lollipop之前版本的设备或模拟器上运行。下面截图展示了AppCompat版本的ToolbarFun在Nexus 4(系统KitKat API 19)上的运行情况:
当使用AppCompat库时,不需要依据Android版本切换主题 —— AppCompat库可以让所有受支持的Android版本上提供一致的用户体验。
译:奇葩史