@operandoOS氏主催のソースを読む会に参加してきた。(@メルカリ) 素敵な雰囲気のオフィスだった。
よい機会だったのでLauncher3を少し読んでみた。
↓ イベントのページ
https://mandroidfcr.doorkeeper.jp/events/33925
↓ しおり
Android Framework Code Readingのしおり
背景
以前Qiitaで RecyclerViewをFragmentPagerAdapter風にする という記事を書いたのだが、
- できるだけ簡単に
- 水平方向で1ページずつ表示する
- スワイプで左右に移動する
- ページの境界線にスナップする
ということがしたかったのだった。
これはAndroidのホーム画面で実現されていることなので、もしかしてライブラリとして提供されていて簡単に使えたりするのではと何となく思っていた。
ぐぐった結果 このへん などから、ホーム画面のアプリはLauncherという名前らしいことがわかった。
OpenGrok
で調べてみたところ、Launcher2とLauncher3というアプリが存在していたので、今回はLauncher3を読むことにした。
$ git clone https://android.googlesource.com/platform/packages/apps/Launcher3
でローカルに落としてきてSublime Text3で読んだ。
Pagerをさがす
まずページをホストしている部分を探した。手がかりとしてresからホームボタンのアイコン (:::) を探して
drawable-xhdpi/ic_allapps.png
を発見。
これをres以下でgrepして、launcher.xmlの中で
com.android.launcher3.Workspace
AllApps (※ コメント)
page_indicator
のような感じに並んでいるのを発見。
WorkspaceがPagerの部分だとあたりをつける。
res/xml/default_workspace_4x4.xml
res/xml/default_workspace_5x5.xml
res/xml/default_workspace_5x6.xml
というファイルがあり、解像度ごとにグリッドレイアウトをXMLで切り替えているような気がする。意外とローテク。
src/com/android/launcher3/Workspace.javaにて、PagedViewを継承していたのでPagedViewを読むことに。
PagedView
お目当てのソースはこれだった。CellLayoutを複数持つpagerらしい。
2400行くらいあって、割と場当たり的に書かれている印象。読みやすいといえば読みやすい。
手を離したらスナップする部分は MotionEvent.ACTION_UP の部分で、このcase文だけで100行あるのでちょっと長い。個人的には真面目すぎるコードの方が苦手なので、こういうadhocっぽいソースをリリースするのは好感が持てる。たぶんさほどcriticalな部分ではないのでそんなにシビアに管理していないのだろう。
よくわからないのでついでに~/Library/Android/sdk/sources/android-22/android/support/v7/widget/LinearLayoutManager.javaも少し読んだ。(こちらはAndroid Studioと一緒にインストールされているもの。とてもソースがきれい。)
小ネタ的にわかったこととして、ゆっくり中途半端な位置で手を離したとき、次の画面に行くかどうかの閾値は0.4だった。すなわち40%以上動かしていれば次の画面に行くということ。(速く動かしたときは勢いで次の画面に行く)
定数でぐぐったら、どうやら同じ部分を読んでる人がいた。読めないけど。
http://www.yuanhh.com/2015/09/20/android-launcher-1/
感想
Launcherをそのまま再利用するのは難しそう、ということはわかったが、色々コメントは書かれているし、あとでもう少し読んでみて参考にしたいと思う。
@operandoOS氏から紹介された方法として、
$ adb shell dumpsys activity top
でアプリやViewの要素を列挙すれば、上の部分(Workspaceとか)は一発でわかる。5.0のシミュレータで実行したところ、Launcher2と出てきたので、使っているのはLauncher2のほうなのかもしれない。ツールを使って調べるのと、ソースを読むのを行き来するのが良さそうだ。
adbを使いこなしていないので、今後の開発に生かしていきたい。
少しだけ深い部分を読むというのはとても良い試みだと思った。思い出したときにどんどん読んでいきたい。