使用 Material Design

本文从 配置工程使用资源 两方面介绍如何使用 Material Design。

配置工程

关于此任务

由于 mPaaS 框架的特殊性,若直接在项目中引入 AppCompat 相关库,编译时会报错,提示资源找不到。为了解决该问题,mPaaS 提供了自定义的 AppCompat 库。要使用 mPaaS 自定义的 AppCompat 库,首先要配置 Portal 工程和 Bundle 工程。

mPaaS AppCompat 库基于原生 Android 23 版本开发,包含以下组件:

  • appcompat

  • animated-vector-drawable

  • cardview

  • design

  • recyclerview

  • support-vector-drawable

由于该自定义的 AppCompat 库是基于原生 Android 23 版本编译,和原生并无区别,只是解决了引入原生库的一系列编译问题。

使用资源的情况主要包括 使用另一个 Bundle 中的资源对外提供资源在 AndroidManifest 中使用自定义资源。由于 mPaaS 框架的特殊性,您需要了解使用资源不同情况下的注意事项。要了解具体内容,查看 使用资源

操作步骤

  1. 配置 Portal 工程。

    在调用 mPaaS AppCompat 库前,完成以下操作配置 Portal 工程:

    1. 运行以下命令将 Gradle 打包插件(Alipay Plugin for Gradle)版本替换为以下版本:

      classpath 'com.alipay.android:android-gradle-plugin: 3.0.0.9.13'
    2. 移除 Gradle 脚本中原先依赖的 AppCompat 库。

    3. 在 Gradle 脚本中添加以下 AppCompat 依赖:

      bundle 'com.mpaas.android.res.base:mpaas-baseresjar:1.0.0.180626203034@jar'
      manifest 'com.mpaas.android.res.base:mpaas-baseresjar:1.0.0.180626203034:AndroidManifest@xml'
    4. 配置完成后,使 Bundle 工程调用 AppCompat 组件,同步 Portal 工程。

  2. 配置 Bundle 工程。

    1. 在需要使用 AppCompat 组件的 Bundle 工程中,将 Gradle 打包插件(Alipay Plugin for Gradle)修改为以下版本:

      classpath 'com.alipay.android:android-gradle-plugin: 3.0.0.9.13'
    2. 根据您使用组件的情况,选择需要依赖的子组件。以下为添加 recyclerview 的示例语句:

      provided 'com.mpaas.android.res.base:mpaas-baseresjar:1.0.0.180626203034:recyclerview@jar'

使用资源

Material Design 常见的资源包括 String、Color、Style 等。使用资源的情况主要包括:

检测 Package ID 是否重复

如果按照本文的说明使用资源时,出现资源找不到的情况,您需要查看 Package ID 是否重复。Package ID 定义在 build.gradle 中,其 ID 值与生成的资源 ID 有关。重复定义 Package ID 会导致资源找不到的情况。

您可以通过以下两种方式检测 Package ID 是否重复:

方式一:通过 gradle task 自动检测

前置条件

android-gradle-plugin 的版本号为 3.0.0.9.13 及以上。如:

classpath 'com.alipay.android:android-gradle-plugin: 3.0.0.9.13'
检测步骤
  1. 在 Portal 工程根目录下,执行以下命令:

    • Windows 系统:执行 gradlew.bat checkBundleIds

    • 其它操作系统:执行 gradlew checkBundleIds

  2. 检查输出结果:

    • 若输出结果包含 No duplicate bundle ids found,说明 Package ID 没有重复。

    • 若输出结果包含 There are duplicate bundle ids,说明 Package ID 有重复。您可以根据输出结果进一步判断具体是哪些 Package ID 重复。

方式二:手动检测

手动检测适用于任何情况,具体步骤如下:

  1. 在 Portal 工程以下位置打开 bundles.csv 纯文本文件。

  2. PackageId 列进行排序,查看有无重复的 Package ID;确保没有重复的 Package ID 后再重新编译。

使用另一个 Bundle 中的资源

场景示例

使用 mpaas-baseresjar 中的资源属于该情况。在使用另一个 Bundle 中的资源时,必须要加上资源的命名空间。命名空间为资源所在 Bundle 的 applicationID,构建 release 包时可能会出现如下图的错误:

解决方法

build.gradle 下配置 lintOptions,配置方法如下图所示:

只要引用该 Bundle 中的资源(包括在 layout 中引用、在自定义 style 中引用等),就必须加入命名空间作为前缀。否则,会出现资源找不到的编译错误。

代码示例:在 layout 中引用

以在 layout 中引用另一个 Bundle 中的资源为例,使用的代码示例如下所示:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res/com.mpaas.android.res.base"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_scrolling"
        android:layout_width="match_parent"
        android:layout_height="@dimen/app_bar_height_image_view"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay"
        android:background="@color/blue">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:contentScrim="?com.mpaas.android.res.base:attr/colorPrimary"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/image_scrolling_top"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="fitXY"
                android:src="@drawable/material_design_3"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?com.mpaas.android.res.base:attr/actionBarSize"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay" />

        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_scrolling"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/big_activity_fab_margin"
        android:src="@drawable/ic_share_white_24dp"
        app:layout_anchor="@id/app_bar_scrolling"
        app:layout_anchorGravity="bottom|end" />

    <include layout="@layout/content_scrolling" />

</android.support.design.widget.CoordinatorLayout>

代码示例:在自定义 style 中引用

以在自定义 style 中使用另一个 Bundle 中的资源为例,使用的代码示例如下所示:

    <style name="AppTheme" parent="@com.mpaas.android.res.base:style/Theme.AppCompat.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="com.mpaas.android.res.base:colorPrimary">@color/colorPrimary</item>
        <item name="com.mpaas.android.res.base:colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="com.mpaas.android.res.base:colorAccent">@color/colorAccent</item>
    </style>

对外提供资源

  1. 配置 Portal 工程。在 Portal 中引入资源 Bundle 的信息:

    // 引入提供资源的 bundle
    bundle "com.mpaas.demo.materialdesign:materialdesign-build:1.0-SNAPSHOT:raw@jar"
    manifest "com.mpaas.demo.materialdesign:materialdesign-build:1.0-SNAPSHOT:AndroidManifest@xml"
    // 为了在编译时能找到资源,还需要 provided 该 bundle 的 jar 包
    provided 'com.mpaas.demo.materialdesign:materialdesign-build:1.0-SNAPSHOT:raw@jar'
  2. 定义资源。完成以下步骤定义资源,以使得资源可被其他的 Bundle 或者 Portal 引用:

    1. 将需要对外提供的资源 id 定义在 public.xml 中,以达到固定资源 id 的目的。该能力由 Android 提供。资源 id 值可以从 R.java 中拷贝,示例代码如下:

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
       <public name="AppTheme" id="0x1f030000" type="style" />
       <public name="AppTheme.AppBarOverlay" id="0x1f030001" type="style" />
       <public name="AppTheme.NoActionBar" id="0x1f030002" type="style" />
       <public name="AppTheme.NoActionBar.StatusBar" id="0x1f030003" type="style" />
       <public name="AppTheme.PopupOverlay" id="0x1f030004" type="style" />
       <public name="DialogFullscreen" id="0x1f030005" type="style" />
       <public name="DialogFullscreenWithTitle" id="0x1f030006" type="style" />
      
       <public name="title_activity_login" id="0x1f0c0081" type="string"/>
       <public name="title_activity_recycler_view" id="0x1f0c0082" type="string"/>
       <public name="title_activity_share_view" id="0x1f0c0085" type="string"/>
       <public name="title_activity_scrolling" id="0x1f0c0083" type="string"/>
       <public name="title_activity_settings" id="0x1f0c0084" type="string"/>
       <public name="title_activity_about" id="0x1f0c007f" type="string"/>
       <public name="activity_donate" id="0x1f0c000e" type="string" />
       <public name="activity_my_apps" id="0x1f0c000f" type="string"/>
      
      </resources>
    2. 外部在使用时,在资源前加上包名作为前缀。具体内容,参见 使用另一个 Bundle 中的资源

在 AndroidManifest 中使用自定义资源

如果您在 Bundle 工程的 AndroidManifest 定义了主题,如下代码所示:

<activity
            android:name=".activity.MainActivity"
            android:launchMode="singleTop"
            android:theme="@com.mpaas.demo.materialdesign:style/AppTheme.NoActionBar"
            android:windowSoftInputMode="stateHidden|stateUnchanged">
</activity>

则您需要:

  • Portal 工程的主工程路径下添加 res_slinks 文件,并且将 Bundle 名,逐行添加到 res_slinks 文件中。

  • 同时在 build.gradle 中去掉该 Bundlemanifest依赖 。如下代码所示:

    manifest 'com.mpaas.demo.materialdesign:materialdesign-build:1.0.0:AndroidManifest@xml'