【デザイナー向け】これからAndroidのデザインをする人へ

# はじめに

## 自己紹介

　私は日本にAndroidが上陸したAndroid 1.6の時代(2009年頃)からAndroidの開発者としてAndroid7系になった今も(執筆時2017年)Androidエンジニアを続けています。
Androidの歴史をずっと側で見守り続けた私がエンジニア目線で思っている事を述べるので、これからAndroidのデザインをするデザイナーに見て頂きたいです。
※ この記事の内容は一個人の意見で所属先は一切関係ありません

## 一番言いたいこと

　まず、普段iPhoneを使っているデザイナーは**最新もしくは1つ前のOS**が入ったAndroid端末をメイン端末とまではいかなくても2台持ちにして**常用**して下さい。
**ハッキリ言ってこれが全てです!!**
良さ気なUIのアプリを一通り入れて数十分触るだけでは全く意味がありません。
Androidの良さは通知やIntentと呼ばれるアプリ間の密な連携であったり、自由にカスタマイズ可能なホーム画面、Google NowやNow on Tapの様なiOSには無いAndroid OSの便利な機能がたくさんあるところです。
これらのUXは普段Androidを使用している人にしかわかりません。
　私は普段Androidエンジニアとして働いているので必要経費だと思って毎年最新のAndroidの端末に買い替えつつ、iPhoneをサブで2台持ちしています。お互いのOSの特徴を知って、良いところをUI/UXに活かしたいからです。普段使いもしないモノのUI/UXがデザインできるわけありません。
例えるならば、普段全く料理をしない人がシステムキッチンのレイアウトからデザインを0からしてと言われてデザインするのと同じです。料理自体なんとなくやることはわかっているので、水道やコンロを配置して、収納として上下の棚を…と大体の配置は出来ます。デザインのプロですから一見キレイな見た目のキッチンは完成するとは思います。
ただ、実際に料理をする人の使い方は一切考慮されていないので、いざ使ってみたらコンロ同士の距離が近すぎて大きなフライパンと鍋を一緒に置くと使えないみたいな問題が起きます。
いわゆるUXの部分をカバーすることは出来ません。
iOSで当たり前だと思うことがAndroidでは当たり前じゃありません。逆もまた然りです。

　私の感覚だとデザイナーの役職を名乗る9割以上がiPhoneをメイン端末に使っています。（偏見なので異なっていたら申し訳ございません)
ですが、意外とその内の半数ぐらいはAndroid暗黒時代と呼ばれる2系の端末を所持していた経験があり、Androidに嫌悪感を抱いています。
Androidは2013年10月頃にでた4.4系(通称 KitKat)までは正直使い物にはなりません。ここは認めます。
しかし、通称Lollipopと呼ばれる5系以降(2014年11月頃)に関してはユーザ視点、開発者視点 共に劇的に進化を遂げました。
デザイン業界でも一躍主要な概念となった[マテリアルデザイン](https://material.io/guidelines/)が導入されたのも5系からです。
AndroidをディスるiOSユーザは一旦5系以上の端末(日本, 中国製, 低価格帯は除く)を使用してから言って下さい。5系以上の批判は真摯に受け止めます。

# 基礎編

Androidをデザインする上で最低限知っていなければならないことをまとめました

## dp(dip), sp

　普段デザインをする時に使う単位はpxだと思います。しかし、Androidのデザインをする上でpxという言葉は忘れて下さい。
同じモバイルOSであるiPhoneはAppleからしか発売されません。なに当たり前の事を言っているんだと思うかもしれませんが、かなり大事です。
　Androidはオープンソースソフトウェアと呼ばれるソースコードが全世界に公開されていて、簡単に言うと誰でも好き勝手にイジって使うことが出来るOSです。つまり、各メーカーが自分達が最高だと思う好きな形の端末に導入して販売することが出来ます。
これにより、単一メーカーが販売するiPhoneでは起こり得ない画面サイズの差異の問題が生じます。
この問題を解決するためにGoogleはdp, spという手段で解決しようとしました。

### dp

dpはdensity-independent pixelsの略で日本語にすると密度非依存ピクセルと呼ばれます。
要するにディスプレイサイズが異なっていても同じサイズ（見た目）で表示することが出来るサイズです。
中身の計算はOSがしてくれるので、デザイナーやエンジニアは画面サイズを気にせずに同じ値を使うことが出来ます。

Google本家サイトから持ってきたので多少UIが古いですが
dpがない場合はこのように表示されます

![density-test-bad.png](https://qiita-image-store.s3.amazonaws.com/0/22527/be31da46-0802-f95b-b3d0-9c6d949ced65.png)

https://developer.android.com/images/screens_support/density-test-bad.png

dpがあると同じ様なサイズで表示されます

![density-test-good.png](https://qiita-image-store.s3.amazonaws.com/0/22527/2527318a-f816-6e36-8d74-75faa5d0184b.png)

https://developer.android.com/images/screens_support/density-test-good.png

　ただし、dpはdpi(dots per inch)と呼ばれる1インチ中に何dot含まれているかを元に計算されているので、
基準dpiからズレた端末の場合は若干表示がズレますが、気にするほどでは無いでしょう。
これは、基準から外れた端末を作るメーカーが悪いです。
2系の頃はよくあったのですが、最近では減ったというよりかほぼ無いと思います。

### sp

spはscale-independent pixelの略でdpのテキストサイズバージョンです。
AndroidではOSの設定から文字サイズの変更を行えます。
これはiOSでも出来るのですが、iPhoneではApple純正アプリやFacebook, Twitter, Instagramのような世界でも有名なアプリはさすが対応しているのですが、その他のサードパーティアプリではユーザが設定した文字サイズを無視してサービス側のサイズ指定がされているアプリが大半です。
AndroidではiPhoneとは異なり そもそも複数画面サイズがある前提なので、Googleも推奨している通りユーザが設定した文字サイズを尊重し、**大きな文字サイズが指定されている場合も考慮された**デザイン設計が必要となります。
難しいように思えますが、テキストもspを用いればdpと同じようにOSが画面密度に加えてユーザのフォントサイズから計算して適切な値にしてくれるので、画面サイズが異なる端末でも同じようなデザインにすることが出来ます。

これらの概念は本家android developerで解説されているので読んでみて下さい。

https://developer.android.com/guide/practices/screens_support.html

## display size

### 汎用密度

 Android 3.2まではsmall, normal, large, xlargeと呼ばれる4つの概念だったのですが、現在はmdpiを基準とした6つの画面サイズで管理されています。
今後も技術の発展により高画質化が進むと思われますので `xxxxhdpi`になるのか、一旦リセットして見直されるのかはわかりませんが。

|汎用密度|dpi|倍率|dp|px|
|:-:|:-:|:-:|:-:|:-:|
|ldpi（low)|～120dpi|x0.75|4dp|3px|
|mdpi（medium）|～160dpi|x1|4dp|4px|
|hdpi（high）|～240dpi|x1.5|4dp|6px|
|xhdpi（extra-high）|～320dpi|x2|4dp|8px|
|xxhdpi（extra-extra-high）|～480dpi|x3|4dp|12px|
|xxxhdpi（extra-extra-extra-high）|～640dpi|x4|4dp|16px|

 AndroidのMargin等を見てみると8dpや16dp等、よく4の倍数が用いられます。
なんかわからないけど、とりあえずsampleが16dpだから16dpを使ってるみたいな人もいるかと思いますが主に4の倍数を使う理由がここにあります。
画面サイズはmdpiを基準として2倍、3倍となるので4の倍数でデザインをすると画面サイズが変わってもキレイなレイアウトを保つことが出来ます。
なので、デザイナーの方はmarginやpadding, 各コンポーネントのサイズを基本的には**4の倍数**で指定するようにして下さい。(もちろん例外はあります)

### タブレット対応

　普段からPCを使い倒している開発者目線で見るとわからないかと思いますが、世の中には想像以上にAndroidのタブレットを使用している人がいます。中華端末などタブレットは1~3万円の価格帯で7インチ~10インチの手頃なサイズの端末が手に入るので、動画を見たり文章を読む事が多いようです。(主観)
PCが無い家の人はPC代わりに使っていたりもします。
どこからがタブレット端末なんだ？と言われると定義は曖昧ですが、[Android内部のコード](https://android.googlesource.com/platform/frameworks/base/+/0c4ccff36930ff4f0292b94ad51e164c9fa060a3/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java#813)を見ると600dp以上の端末をタブレットとして判定しています。

Google developersでもタブレットとスマートフォンのレイアウトを分けることが推奨されています。
https://developer.android.com/images/fundamentals/fragments.png
https://developer.android.com/training/design-navigation/multiple-sizes.html

 Androidの仕組みとして、画面サイズからレイアウトを分けることは難しくないので対応可能なのですが、
スマートフォンにはあるけど、タブレットには無い等の機能がある場合は工数がかかるのでエンジニアの人と相談してみて下さい。

また、タブレット対応をする上で気をつける点がもう一つあります。
Androidにはナビゲーションバーと呼ばれるエリアに3つのボタンがあります。
これはiOSには無い概念です。

|名前|記号|意味|
|:-:|:-:|:-:|
|Back|◁|戻る|
|Home|○|iOSのホームとほぼ同じ|
|Recently Tasks|□|iOSのホームボタン2度押しとほぼ同じ|

このナビゲーションバーがスマートフォンの場合は横画面にした場合は右側に配置されるのですが、タブレットは下側に表示されます。
さらに、ソフトウェアキーボードではなくハードウェアキー(通常 静電方式のタッチ)の場合があります。これにより、端末によってレイアウトが変わるのでデザインをする上では注意が必要です。

* smart phone

![smartphone.png](https://qiita-image-store.s3.amazonaws.com/0/22527/c657ba05-58fa-368b-7e41-38471e28d69f.png)

* tablet

![tablet.png](https://qiita-image-store.s3.amazonaws.com/0/22527/dbada580-91eb-60da-572c-ca587c47421f.png)


### 端末サイズ一覧

　海外端末が多いですがGoogleの[Material.io](https://material.io/)のページを見ると、dpとpxが記された端末のサイズ一覧を見ることが可能です。
https://material.io/devices/

こちらのページにある端末がAndroidのデファクトスタンダードになりますので、本当はこちらに合わせるのがベストですが、日本だと独自にカスタマイズされた端末達と戦う事になります…
お互い頑張りましょう💪🏼

## iOSとの違い

### 戻るという概念

　戻るボタンはiOSを使っている人には存在しない概念です。iOSのアプリは遷移したら大抵左上に戻るボタンがアプリ側で用意されています。Androidでは、そもそもBackボタンが存在しているので、最悪UIにボタンが無くても前の画面に戻る事が可能です。（作りにもよりますが）
　そのため、4系以前はあまり戻るボタンは配置されていませんでした。しかし、4系あたりからToolBar(旧ActionBar)の概念が導入されました。これによりアプリの左上に戻るボタンやハンバーガーアイコンを置くことが多いです。ただし、左上の戻るボタンは単に前の画面に戻るとは意味が異なる事があります。

　例えば、電話帳アプリAから詳細面A’に移動して、メールを送るボタンからGmailアプリBのメール作成画面を起動します。
遷移としてはこのようになります

`A -> A’ -> B`

- back key

Bの状態から端末のバックキー（ボタン）を押した場合は前のアプリの最後の遷移画面に戻ります。
`A -> A’ -> B -> A'`

- back arrow button

Bの状態でアプリの左上にある戻るボタンを押した場合は前のアプリに戻らずにBアプリのホーム画面に移動します。
`A -> A’ -> B -> B'`

 実装によるので全部がこのような挙動になるかと言われると保証は出来ないのですが、
まともなAndroidエンジニアならばこの違いを知っていると思いますので、上記の挙動をとらない実装をしている場合は理由を聞いてみると良いです。やむを得ない理由があるのかもしれませんが、エンジニアの知識不足の可能性が高いので修正を頼みましょう。

cf. https://developer.android.com/training/design-navigation/ancestral-temporal.html#ancestral-navigation

### Navigation Drawer

　iOSではGoogle系のアプリ以外はほとんど見かけません。あったとしても、画面左外から右にスワイプするとドロワーと呼ばれるメニューが出て来る概念は普段Androidを使っていない人からすると出てこないでしょう。iOSで画面左外からのスワイプはRecently task(ホームボタン2回押し)と同じ動作になるので、割当難いというのもあると思います。
　Androidユーザからすると、こちらの動作は一般的なのでグローバルメニューがたくさんある場合のデザインとして使うと良いです。

https://material.io/guidelines/patterns/navigation.html#

### Bottom Navigation

　昔は、iOSは下タブが一般的なため、Androidも同じデザインを渡されて作りました。みたいなアプリが多かったので酷かった思い出があります。Android 6以前では下タブは悪とされてました。もちろん私も否定派でした。
　しかし、突如としてMaterial designのガイドラインにBottom Navigationと呼ばれる下タブが追加されて、古くから開発をしているAndroidエンジニアに衝撃を与えました。ただ単にiOSと一緒のタブを使っても良いわけでは無いので、デザイナーの方はこちらのページを入念に読んでガイドラインから大きく外れる事のないようにしましょう。

https://material.io/guidelines/components/bottom-navigation.html#bottom-navigation-specs

### WebView

　iOSはintentという概念が無いので、よく使われます。
特にビジネスサイドの人間はiOS率が圧倒的に高いので、WebViewでの実装が当たり前だと思っています。(偏見)
AndroidのWebViewは日本製の~~クソ~~端末のせいで、意味の分からないカスタマイズが横行して今なお開発者を苦しめ続けています。そのため、ユーザ視点でも開発者視点でもなるべくWebViewを使いたくありません。
WebViewを使う理由はトラッキング以外にほぼ無いと思います。ユーザには何のメリットもありません。
そのような仕様を渡してくるビジネスサイドの人には上記の内容を説明して納得してもらいましょう。
納得出来ないビジネスサイドの人間は技術に理解が無いので、諦めて転職するのが手っ取り早いと思います。
TwitterやFacebookアプリもデフォルトはWebViewでリンクを開きます。ただ、ちゃんと設定画面でIntentを飛ばせるようになっています。おそらく、ビジネスサイドの意向でトラッキングをしているのでしょうが、優れたエンジニアがAndroidの利点を理解しているのでこのようになっているのだと思います。
最近では[Chrome custom tab](https://developer.chrome.com/multidevice/android/customtabs)の登場により、かなりマシにWebViewっぽいことが出来るようにはなり、速度も早くなったのでこちらの選択肢も出てきましたが、ユーザ視点ではIntentで飛ばしてくれる方が好きなアプリで開く事が出来るので嬉しい時もあります。

# 実践編

## 画像

　上記でも説明しているようにAndroidでは画面サイズが多岐にわたるので、画像を用いる場合は各画面サイズ毎に異なるサイズの画像を用意しなければなりません。
これはiOSでも同じことが言えますが、価格帯が安いAndroidは新興国等の通信環境が悪い国ほど利用されている傾向にあるため、アプリ(apkファイル)のサイズが増えることは好ましくありません。以前はアイコン1つ1つ追加する毎に画像ファイルが複数増えていくので、好ましい状況ではありませんでした。
対策として、Android OSにはそもそもアイコンが用意されているので同じ目的のアイコンは[既存のもの](https://material.io/icons/)を利用したり、フォントにアイコンを割り当てて疑似ベクターとして利用する方法を用いてこの問題を回避していました。
しかし、Android Studio 1.4が出た2015年辺りから公式にSVGがサポートされ、現在ではベクターを利用するのが一般的です。さらにAndroid Studio2.3(2017年3月リリース)からはWebPが正式にサポートされ、ベクターでは表せず、やむを得ず画像を使わなければならない場合でも画像サイズの縮小が可能になりました。
これからAndroidのデザインをするデザイナーの方は、基本ベクターでデザインをして、やむを得ず画像を使う場合はWebP形式でエンジニアの方に画像ファイルを渡しましょう。

## 基本構成

　Androidではレイアウトの情報は基本的に以下のような構成になっています。
付ける名前は何でも良いので、もちろんプロジェクトによって名前が違ったり、あるファイルや無いファイルがあります。
ここから先の情報はプロジェクトによって大きく異りますのでご注意下さい。 名前は異なっていても大枠は似たような構成になっているはずです。

```
project
 |_ app
     |_ src
         |_ main
             |_ assets
             |_ java(kotlin)
             |    |_ ...
             |_ res
                 |_ drawable
                 |_ drawable-hdpi
                 |_ drawable-mdpi
                 |_ drawable-xhdpi
                 |_ drawable-xxhdpi
                 |_ layout
                 |_ values
                      |_ colors
                      |_ dimens
                      |_ strings
                      |_ styles
                      |_ ...

                 |_ ...
```

Androidのリソースファイルはxmlファイルで管理されています。

リソースディレクトリ(res)以下を簡単に説明すると、

* `/drawable`  
 画像やxmlで書かれた画面サイズに依らないボタン等のファイルが入ります
* `/drawable-***`  
 各画面サイズ毎のdrawableにある画像ファイルを同じ名前で入れます
* `/layout`  
 xmlで書かれたlayoutファイルがあります。もしデザインを少しズラしたい等の場合はここの中のファイルを変更することになると思います。  
Android Studio 2.2 Preview(2016年5月)からは[ConstraintLayout](https://developer.android.com/training/constraint-layout/index.html)というiOSでいうとAutoLayoutと似た機能が追加されて、マウスでも配置が出来るレイアウトが登場しました。
ただプロジェクトによっては、まだ導入していないところが多数だと思いますので、使えない場合の方が多そうです。
Androidを長くやっている私はレイアウトを見ると一瞬でxmlのタグが思いつく特殊能力を身に着けてしまったのでConstraintLayoutを使うつもりは無いのですが、Androidを始めたばかりの人には良いかもしれません。
* `/values`  
 デザインのベースとなる部分を記した複数のファイルが入っています。デザイナーが一番見るべきはここ以下のファイルかもしれません。

values内の各ファイルについても軽く説明します

* `colors.xml`　　　

 その名の通りcolorが記されています。各色に名前を付けられるのですが、 

```xml  
<color name="blue">#0c00cc</color>
```
 みたいな使い方は止めましょう。
 全く意味が無いわけでは無いですが、colorsの意味が無いです。
 デザイナーの方はデザインをする上で必ず、キーカラーやアクセントカラーを付けると思います。
 本来colorsの中身はそのようになっているべきです

```xml
<color name="primary_color">#2D8C3C</color>
<color name="accent_color">#82be28</color>
```
 
* `dimens.xml`　　

dpやspで記されたサイズ一覧
ここもこのように一箇所でしか使われない各サイズを全て記していたら、dimensの意味が無いです。
もちろん例外もありますが、そもそも一箇所でしか使われないパターンというのは、デザイン設計に誤りが有ることが多いです。

```xml
<dimen name="home_image_width">120dp</dimen>
<dimen name="home_image_height">80dp</dimen>
```

例えば、アイコンのサイズはアプリ内で予め決められたサイズしか無いと思います。
そのような場合に、以下のように定義しましょう。

```xml
<dimen name="icon_large">80dp</dimen>
<dimen name="icon_medium">40dp</dimen>
<dimen name="icon_small">24dp</dimen>
```

* `strings.xml`　　
 アプリ内で表示する文字列一覧。ここは多言語対応する際に各言語毎に複数ファイルが作られます。

* `styles.xml`　　
アプリのテーマや、テキストのスタイル、厳密には違いますがCSSでいうコンポーネントのようなものが書いてあります。このファイルが特にプロジェクトによって大きく差が出るのでエンジニアの人にどう管理されているか聞いてみましょう。

　個人的にはAndroidのxmlはCSSにとても良く似ていると思います。
デザイン設計が崩壊している場合はvalues以下の設計が崩壊していることが多いです。
エンジニアの技術力? 整理力?によって良いデザインでも崩壊し得るので一概には言えませんが、values以下のファイルが整理整頓されているプロジェクトはデザインの変更が容易で、美しいデザインのアプリが多いです。
　デザイナーの方は、values以下のファイルがきちんと整理されていなかったらエンジニアに何故こうなっているかを問いただしましょう。自分がデザインした設計が完璧ならば、整理整頓されているはずです。逆に、values以下が汚い場合はデザイナーのデザイン設計が誤っているのかもしれません。自分のデザイン設計を見直して下さい。


## アンチパターン

AndroidエンジニアはiOSと同じデザインが大嫌いです。「iOSと全く同じようにして」なんて言われた日には全てのやる気を失います。
自社開発では ほぼありえないかと思いますが、受託のサービスではよく見かけます。
そんなデザインを渡すデザイナーはデザイナーを名乗らないで欲しいです。
少し古いですが、GoogleがiOSとの違いを丁寧に書いてあるので参考にしてみて下さい。
https://design.google.com/articles/design-from-ios-to-android/
_後から見つけたので、よく読んでみたらこの記事と半分以上内容が被っていたのですが、あえてそのままにします…_



## プルリクエスト(Pull Request)

　ここまで理解していると、よくエンジニアが発しているプルリクエスト通称プルリクというものが出来るかもしれません。
「ちょっとここのmarginを右に4dp動かしたいけど、エンジニアに頼みづらいな…」 みたいな時に自分で変更出来るデザイナーは強いです。エンジニアからの信頼も上がると思います。
普段Gitを使っていないと、概念を理解するまで少し難易度が高いですが、デザイン変更をしたプルリクを送ってみましょう。
最初は難しいですが、慣れないうちはエンジニアの人に聞いてみましょう。快く教えてくれると思います。
プロジェクト自体がGitを使っていない場合もありますが、現代ではよほどの事がない限りGitを使ってバージョン管理されていると思います。

# さいごに

日本では圧倒的にiPhone第一主義ですが、世界ではAndroidのシェアが8割8分と全く逆の現象が起きています。日本発の世界的に有名なアプリ（サービス）が出てこないのも、少なからず関係しているのではないでしょうか。いちAndroidユーザとして全てのAndroidアプリのクオリティが上がることを祈って、これからも見守り続けたいと思います。
みんなで世界を良くしていきましょう！