[译]:Xamarin.Android用户界面——工具栏兼容性

标签: 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版本的工具栏,需要以下 几个步骤:

  1. 设置应用的最低和目标Android版本。
  2. 安装AppCompat的NuGet包。
  3. 使用AppCompat主题替换内置的Android主题。
  4. 修改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版本上提供一致的用户体验。


译:奇葩史

没有评论