読者です 読者をやめる 読者になる 読者になる

Android UI/UX アンチパターン

参考資料

Android Developers

画面全般

スプラッシュ画面

必要のないスプラッシュ画面の表示はやめましょう。

なぜダメか

多くのアプリにおいて、スプラッシュ画面では何も処理していません。 このようなアプリでは、ユーザがアプリを起動してからスプラッシュ画面の表示が終わるまでの間、ユーザの時間を単純に浪費してしまいます。 わずかな時間かもしれませんが、Androidではアプリの起動/終了が頻繁に繰り返される場合があるため、デスクトップアプリと比べて表示される頻度が多くなることを意識する必要があります。

解決法

スプラッシュ画面を削除する。 余談ですが、iOSのLaunchImagesは体感上の起動時間を短縮するためにアプリ起動後の画面と似たものを使用することが推奨されています。 Androidアプリにおいて、体感上の起動時間を短縮するためにできることはスプラッシュ画面を削除することです。

iOS Human Interface Guidelines: Launch Images

例外

起動時に重い処理をする必要があるアプリ、特にゲームアプリなどはスプラッシュ画面を設けるべきです。 このようなアプリでは起動から実際に動作が可能になるまでタイムラグが生じるため、可能な限り迅速に何らかの画面を表示する必要があります。

Keeping Your App Responsive | Android Developers

時代遅れのUI

以下の要素はUIを時代遅れと感じさせます。

  • ナビゲーションバーのメニューボタン
  • Gingerbread時代のtheme/style
  • ActionBarを使用していない

なぜダメか

ナビゲーションバーのメニューボタンは古い端末におけるメニューボタンを模したもので、「Menu Button of Shame」とも呼ばれています。 Menu Button of Shameの機能は最近のUIではActionBarのMenuItem、またはオーバーフローメニューに集約されています。

Gingerbread時代のtheme/styleはアプリ全体を古臭くみせてしまいます。 アプリ全体がHoloベースになっていても一部部品が古いままだったりと見栄えが悪いので、細部にも気を配りましょう。

ActionBarを使用せず、TitleBarが表示されてしまうのもアプリを古臭く見せる要因です。 Support Libraryにv7-appcompatが追加されてから1年以上経過しており、ActionBarはすでに一般的な実装になっています。

解決法

  • targetSdkVersionを最新にする
  • ThemeをHoloやAppCompatにする
  • ActionBarを導入する

他のプラットフォームの模倣

以下のような実装は他プラットフォームの模倣です。

  • 下タブバー
  • リスト項目の右向き矢印
  • 非標準ナビゲーション(独自のActionBar、メニューボタン)

Pure Android | Android Developers

なぜダメか

他のプラットフォームを模倣したデザインはAndroidプラットフォームデザインの一貫性を損ないます。 iOSにおいて下タブバーが標準的なUIであるように、Androidでは画面上部のタブバーやNavigationDrawerが一般的です。

リスト項目の右向き矢印に関しては、Androidでは不要です。 直感的だと言われていますが、画面遷移アニメーションが矢印にあわせて実装されていることはほとんどありません。

非標準ナビゲーションはプラットフォームの一貫性を損なうだけでなく、多くの場合拡張性も犠牲になっています。

解決法

まず、Androidプラットフォームの標準的な実装を心がけるべきです。 下タブバーはActionBarのタブ機能を使うか、NavigationDrawerを利用してください。 FragmentTabHostやPagerTitleStripも利用できます。

リスト項目の右向き矢印は削除してください。

非標準ナビゲーションはActionBarに置き換えてください。 ActionBarはある程度カスタムUIを含めることができ、多機能で、拡張性に優れます。

縦向き固定・電話限定

アプリ画面の縦向き固定・スマートフォンのみ対応は賢明ではありません。

なぜダメか

縦向き固定のアプリは純粋に使い勝手が悪いです。 スマートフォンでしか使えないアプリはタブレットユーザに対する機会損失です。 Androidタブレットの普及率は高く、無視するには惜しいレベルです。

タブレットの国内出荷台数は713万台、iOSとAndroidのシェアは1%の僅差 - ケータイ Watch

解決法

Androidではさまざまな解像度に対応するための仕組みが用意されています。 dpで設計し、拡縮範囲、スクロール範囲を意識していれば横画面でも崩れないレイアウトを作るのは難しくありません。 タブレット対応は難しく感じますが、最初から完全なマルチペインが必須なわけでもありません。 表示崩れを防ぎ、タブレットでも十分に操作できるというレベルにするのは他画面対応できていれば思ったよりも簡単です。

Supporting Multiple Screens | Android Developers

Designing for Multiple Screens | Android Developers

ダイアログ

確認ダイアログの多用

あるアクションに対しそれを続行するかどうかを選択させるダイアログのことを確認ダイアログといいます。 確認ダイアログを多用しないでください。

なぜダメか

Androidにおいて、確認ダイアログを利用すべきシチュエーションは2パターンのみです。

  1. ユーザがその処理を実行する前に結果を警告する必要がある場合(決済やリセットなど)
  2. ユーザが誤って実行した場合に不利益となり、かつ技術的に元に戻せない場合(データ削除など)

これ以外のシチュエーションにおいて、ユーザに確認ダイアログを表示する処理は非推奨となります。

Confirming & Acknowledging | Android Developers

解決法

Confirming & Acknowledgingの内容に従って実装する必要があります。 その上で誤操作が頻繁に起きるような場合、UI上の混乱が原因となっている場合が多いので、UIの見直しを検討してください。 ActionBarのメニューにする、アイコンをわかりやすいものに変更するなど確認ダイアログに頼らない方法があるかもしれません。 事前に防ぐだけではなく、アクション後に取り消せるような動線を用意するのも良いと思います。

読み込み中ダイアログの多用

読み込み中ダイアログ(プログレスダイアログ)とは、非同期処理の実行中に表示するダイアログを指します。

なぜダメか

読み込み中ダイアログは、多くの場合、キャンセルが無効(setCancelable(false))にされています。 この場合では非同期処理であってもユーザが画面を操作できないため、ユーザ体験を損ないます。 キャンセル可能なダイアログであっても頻繁に表示されたり、時間のかかる処理が誤タッチで中断してしまうと悪印象になる恐れがあります。 また、実装上の問題として読み込み中ダイアログをDialogFragmentで実装する場合に処理が複雑になりがちです。

解決法

SwipeRefreshLayoutなどを利用し、画面操作を必要以上に阻害しない形で読み込み中表示を行います。 SwipeRefreshLayout#setEnabled(false)で、スワイプ更新機能を無効にしてプログレス表示機能のみを利用することができます。 ListFragmentは標準でsetAdapterされるまで読み込み中表示を行う機能があるため、これを利用することも検討してください。

例外

仕様上、どうしてもキャンセルさせたくない処理というものも存在します。 IntentServiceを利用する方法もありますが、画面と密に連動している場合などやはり読み込み中ダイアログを利用したほうが良い場面もあります。 読み込み中ダイアログをすべて無くそうとするよりも、必要な箇所だけに限定できないか検討してください。

ダイアログの独自アクションボタン

Androidでは通常、ダイアログ下部に「OK」「キャンセル」といったアクションボタンを表示します。 これらとは別に、カスタムレイアウトを利用してダイアログ内に独自のアクションボタンを配置することがあります。

なぜダメか

Androidのダイアログアクションボタンの配置はOSのバージョンによって異なります。 古い端末では左側が肯定ボタンでしたが、ICSからは右側が肯定ボタンになっています。 独自にこれらのボタンを実装する場合、バージョンごとにレイアウトファイルを用意しない限り、OS標準から外れることになります。

解決法

標準のダイアログアクションボタンを使用します。 AlertDialog.Builder#setPositiveButtonなどを利用することで、OSバージョンによって適切な表示を行ってくれます。

例外

凝ったカスタムダイアログを表示したい場合など、OS標準のアクションボタンではダメな場合があります。 その場合でもなるべくシステム内の一貫したユーザ体験を損なわないように注意してください。

操作に関して

タッチ領域が小さすぎる

ボタンなど、タッチ可能なView要素の表示領域は一定以上必要です。

なぜダメか

うまくタッチできないView要素はユーザ体験を損ないます。 以前は縦横共に48dp以上必要となっていましたが、Material Designガイドラインでは一部違う例もあります。

Metrics and Grids | Android Developers

解決法

基本的には表示サイズを一定以上にする必要があります。 どうしても表示サイズを拡大できない場合、TouchDelegateを利用してタッチ領域を広げる方法を検討してください。

Managing Touch Events in a ViewGroup | Android Developers

タッチ時のフィードバックがない

タッチ可能なView要素では、タッチフィードバック(タッチした際のView要素の状態変化)の実装が必要です。

なぜダメか

タッチパネルではマウスと違い明確なタッチポイントがわかりません。 ユーザにどのView要素がタッチされたかを通知するために、タッチフィードバックの実装が必須となります。 特に画面遷移を行うような場合では間違えてタッチしても画面遷移が終わるまでユーザにわからないため、悪印象となります。

解決法

Viewの状態(states)によって見た目が変わるように設定します。

Touch Feedback | Android Developers

AndroidTVやChromebookなど、将来的にタッチパネルでない端末も増えることが予想されるので、pressedだけでなく、focusedも実装しましょう。 Material Designガイドラインではstatesによる描画の切り替えだけではなくアニメーションによるフィードバックも行うようになります。

Responsive Interaction - Animation - Google design guidelines

ジェスチャの間違った利用

Viewの長押しで独自のアクションを実行する、リストアイテムをスワイプして削除ボタンを表示させるというような動作は推奨されません。

なぜダメか

Androidにおいて、ジェスチャの種類とそれぞれのジェスチャがどのような動作をすべきかは決められています。

Gestures | Android Developers これらのジェスチャを異なる意味に用いるとユーザが混乱する場合があります。

解決法

たとえばメニューアイテムの削除であれば、削除(Long Press)によってContextual Actionを呼び出し、複数選択して削除できるような実装にするのが自然です。 単独でアクションさせる場合はfloating context menuによって操作を選ばせる方法もありますが、ジェスチャページではContextual Menuのために長押し操作を利用するなと書いてあるため、なるべくContextual Actionによる実装を検討してください。

Menus | Android Developers

例外

GmailのSwipe-to-Dismiss(スワイプすると削除)のように、標準ジェスチャと異なる実装であっても問題ない場合もあります。 その場合はViewPagerなど既存のジェスチャと競合しないこと、他のアンチパターンに抵触しないことに気をつけてください。 例えばSwipe-to-Dismissの場合、削除時に確認ダイアログを出すとテンポが悪くなります。

共有機能の独自実装

SNSごとに共有ボタンを置くような実装は推奨されません。

なぜダメか

これらは多くの場合、仕様を決める際の考慮漏れです。 本当に必要なのはTwitter,Facebookなど特定のSNSへの投稿ではなく、Twitter/Facebookを含むSNSなどへの拡散ではないでしょうか。 そうであった場合、MixiやG+など他のSNSへ拡散される機会を損失しています。 このような仕様は避けるべきです。

Pure Android | Android Developers

解決法

単純に他アプリへ共有したい場合、暗黙的Intentを発行すれば良くなります。 ユーザの利便性を考慮し、ShareActionProviderを利用することもできます。 どうしても明示的にTwitter/Facebookに投稿させたい場合、アプリがSDKを使用して直接投稿すべきです。

Adding an Easy Share Action | Android Developers

何らかの理由で特定アプリのみ挙動を変えたい場合、Intent.createChooserで対応できる場合があります。

Y.A.M の 雑記帳: Facebookとそれ以外でACTION_SENDで渡すテキストを変える

例外

最終的には連携先のアプリによってしまうので、どうしても解決できない場合もあります。