[この記事は Ben Weiss、デベロッパー プログラム エンジニアによる Android Developers Blog の記事 "More Material Design with Topeka for Android" を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。]

マテリアル デザインは、視覚、インタラクション、モーション デザインの新しい仕組みです。元々、Topeka ウェブアプリはウェブ上のマテリアル デザインのオープン ソース サンプルとして開発されました。

去る 6 月、新しいマテリアル デザインのサンプルである Topeka の Android 版を公開しました。このサンプルを見れば、同じブランドの方針とマテリアル デザインの方針に従って、複数のプラットフォーム間で一貫した操作感を実現できることがわかります。コードは GitHub からダウンロードできます。


多彩な機能

このプロジェクトではマテリアル デザインのさまざまな特徴を見ることができますが、特に興味深いものを紹介します。

遷移


Android 用 Topeka には、遷移を実装するいくつかの機能があります。まず 1 つ目は ActivityOptions にある Transitions API です。これを使えば、簡単かつ効果的にアクティビティ間の遷移が行えます。

これを行うために、リソース ファイルに次のような共有の文字列を登録します。
<resources>
    <string name="transition_avatar">AvatarTransition</string>
</resources>
登録した文字列を、ソースとターゲットのビューで transitionName として使用します。
<ImageView
    android:id="@+id/avatar"
    android:layout_width="@dimen/avatar_size"
    android:layout_height="@dimen/avatar_size"
    android:layout_marginEnd="@dimen/keyline_16"
    android:transitionName="@string/transition_avatar"/>
次に、実際の遷移が SignInFragment で実行されるようにします。
private void performSignInWithTransition(View v) {
    Activity activity = getActivity();
    ActivityOptions activityOptions = ActivityOptions
            .makeSceneTransitionAnimation(activity, v,
                    activity.getString(R.string.transition_avatar));
    CategorySelectionActivity.start(activity, mPlayer, activityOptions);
    activity.finishAfterTransition();
}
ActivityOptions で複数の遷移を実行する場合は、CategorySelectionFragment をご覧ください。

アニメーション

より複雑なアニメーションの場合は、スコアリングで行ったように、独自のアニメーションを調整できます。
アニメーションを適切に調整するには、すべての要素を慎重に準備することが重要です。AbsQuizView クラスは、質問が回答されると、精巧に作成されたいくつかのアニメーションを実行します。
まずこのアニメーションでは、質問の回答に応じて、フローティング アクション ボタンの色が変わります。色が変わると、ボタンはスケール アニメーションで縮小され、ビューの外に移動します。質問そのものが表示されているビューも、画面外に移動します。このビューを小さい緑色の四角形に縮小させてから、アプリバーの背後にスライドさせます。ビューの前景色は、拡大/縮小時に、直前に消えたフローティング アクション ボタン(FAB)に合わせて変わります。これにより、さまざまなクイズや質問の状態に連続性が生まれます。

これらはすべて、秒単位以下で行われます。若干のポーズ(開始の遅れ)をいくつか適用し、アニメーションに圧迫感を与えず、適度な速度を保つようにしました。

この機能を制御するコードは AbsQuizViewperformScoreAnimation メソッド内にあります。

FAB の配置

最近発表されたフローティング アクション ボタンは、強調させるアクションの実行に優れたツールです。Topeka では、回答の送信に FAB を使用しています。また、FAB は、次のように高さが変化する 2 つの面にまたがります。
これを行うために、トップビュー(R.id.question_view)の高さをクエリして、ビュー階層がレイアウトされたら、FloatingActionButton にパディングを設定します。
private void addFloatingActionButton() {
    final int fabSize = getResources().getDimensionPixelSize(R.dimen.fab_size);
    int bottomOfQuestionView = findViewById(R.id.question_view).getBottom();
    final LayoutParams fabLayoutParams = new LayoutParams(fabSize, fabSize,
            Gravity.END | Gravity.TOP);
    final int fabPadding = getResources().getDimensionPixelSize(R.dimen.padding_fab);
    final int halfAFab = fabSize / 2;
    fabLayoutParams.setMargins(0, // left
        bottomOfQuestionView - halfAFab, //top
        0, // right
        fabPadding); // bottom
    addView(mSubmitAnswer, fabLayoutParams);
}
この動作が初回レイアウト後にのみ行われるようにするため、OnLayoutChangeListener を AbsQuizView のコンストラクタで使用します。
addOnLayoutChangeListener(new OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int l, int t, int r, int b,
            int oldLeft, int oldTop, int oldRight, int oldBottom) {
        removeOnLayoutChangeListener(this);
        addFloatingActionButton();
    }
});

円形の OutlineProvider

API 21 より、円形状マスクの作成が非常にシンプルになりました。ViewOutlineProvider クラスを拡張し、getOutline() メソッドを以下のようにオーバーライドするだけです。
@Override
public final void getOutline(View view, Outline outline) {
    final int size = view.getResources().
        getDimensionPixelSize(R.id.view_size);
    outline.setOval(0, 0, size, size);
}
次にターゲット ビューで setClipToOutline(true) とし、適切なシャドウの形を設定します。
詳細は、Topeka for Android の outlineprovider パッケージをご覧ください。

ベクター型ドローアブル

アプリ全体で複数の場所にアイコンを表示させるには、ベクター型ドローアブルを使用します。GitHub の Material Design Icons のコレクションには、使用可能な約 750 個のアイコンが含まれています。Android デベロッパーにとっての最大の利点は、Lollipop 以降、VectorDrawables をアプリで使用することで、デバイスの画面密度に関係なく、鮮明に表示できる点にあります。たとえば、アイコン リポジトリの戻る矢印 ic_arrow_back は、Android のベクター型ドローアブル形式に適応しています。
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="48"
    android:viewportHeight="48">
    <path
        android:pathData="M40 22H15.66l11.17-11.17L24 8 8 24l16 16 2.83-2.83L15.66 26H40v-4z"
        android:fillColor="?android:attr/textColorPrimary" />
</vector>
ベクター型ドローアブルは res/drawable フォルダに一度保存するだけです。つまり、ドローアブル アセットで使用されるディスク スペースが少なくなります。

プロパティ アニメーション

ViewPropertyAnimator クラス(および便利な View#animate 構文)で用意される標準的な変形機能だけに限らず、ビューのどんなプロパティでも簡単にアニメーション化できます。たとえば、AbsQuizView で、ビューの前景色をアニメーション化するプロパティを定義します。
// Property for animating the foreground
public static final Property FOREGROUND_COLOR =
        new IntProperty("foregroundColor") {

            @Override
            public void setValue(FrameLayout layout, int value) {
                if (layout.getForeground() instanceof ColorDrawable) {
                    ((ColorDrawable) layout.getForeground()).setColor(value);
                } else {
                    layout.setForeground(new ColorDrawable(value));
                }
            }

            @Override
            public Integer get(FrameLayout layout) {
                return ((ColorDrawable) layout.getForeground()).getColor();
            }
        };
後でこのプロパティを使用して、次のように、前景色の変化をある 1 つの値から別の値へとアニメーション化できます。
final ObjectAnimator foregroundAnimator = ObjectAnimator
        .ofArgb(this, FOREGROUND_COLOR, Color.WHITE, backgroundColor);
これは API 12 にも追加されているので特別新しい機能というわけではありませんが、簡単に色の変更をアニメーション化する場合には非常に便利です。

テスト

Android 用 Topeka には、マテリアル デザイン コンポーネントの例が含まれている以外にも、新しいテスト API を使用するユニットとインストルメンテーションのテスト一式が用意されています。この API は「Gradle Unit Test Support」と「Android Testing Support Library」です。実装されたテストを使えば、データモデルの変更に対するアプリの回復力が高まります。障害を早期に見つけられるため、コーディングの精度が増し、容易にリファクタリングが行えるようになります。androidTest フォルダと test フォルダを見れば、これらのテストがどのように Topeka に実装されているかを確認できます。Android でのテストをさらに詳しく学ぶには、「Testing Tools」からお読みいただくことをお勧めします。

次のトピック

Android 用 Topeka を見れば、マテリアル デザインによって Android とウェブ全体で一貫した操作性を実現する方法が分かります。このプロジェクトでは、Android 5.0 SDK と新しい Android Design Library の優れたマテリアル デザイン機能の一部も紹介します。

このプロジェクトでは現在 API 21+ のみをサポートしていますが、AppCompat などのツールや新しい Android Design Support Library を使用して、以前のバージョンをサポートする機能のリクエストがすでに寄せられています。

プロジェクトをご覧いただき、ご意見があればプロジェクトの Issue Tracker からご報告いただくか、Google+ または Twitter からご質問ください。

Posted by Yuichi Araki - Developer Relations Team