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

なら@はてなブログ

福岡で働くスマートフォンエンジニア(おっさん)のブログ。更新頻度がとにかく低いのが悩み。

画面の外からメニューをニュッと表示させたい

iPhoneAndroidのアプリを両方作ってると、AndroidのUI設計・開発のやりづらさが身にしみます。


今回は、画面下のボタン(というかタブをイメージ)をタップすると、下からメニューがニュッと出てくる処理の実装について。まあ、イベントはタップじゃなくてフリックでもいいと思うんですが、今回は主にレイアウトの作り方の話。
一般的によく使いそうですが、ぐぐってみてもあんまり情報がありませんでした(日本語で調べてるからでしょうかね?)


もちろん、デフォルトでメニューキーに関連付けたイベントでメニュー出せば同じ動きになりますが、それだとメニューがかなり味気ない見た目になって、レイアウトの自由度が非常に低いんですね。


上記の要件から、僕は単純に「画面の下にメニューのViewを待機させておいて、イベント拾ったら上に動かせばいいんじゃね?」と考えたんですが、なかなか一筋縄ではいかず。
結果的に、上記の仕様で実装はできたのですが、ちょいとハマりそうなところを。


下から画面にフェードインさせるViewの、直接の親ViewがRelativeLayoutの場合、うまくいきません。
どうやら、RelativeLayoutは、そもそも自分の領域外にあるやつが入ってきても描画してくれない模様。

なので、下記レイアウトでLinearLayoutを上に動かしても、もともと表示されているボタン部分だけがむなしく上に動きます。
f:id:narazoro:20101024030313p:image


で、僕のやり方が最適解だとは思っていませんが、ぱっと思いつくひとつの解法としては、LinearLayoutの中身を動かす方法があります。
XMLの構造(親子関係)は上と同じですが、配置場所と動かす対象が違います。
f:id:narazoro:20101024031154p:image

これで、アニメーション対象をボタンと隠しViewに設定して上に動かしてやれば、目的の動きが実現できます。



で、ここでの注意点。かなり有名な話ですが。
Animationを使ってViewを動かした場合、確かに見た目は動いているのですが、タッチイベント等を拾える領域は動いていません
要するに、Animationを使って画面外からメニューを動かしてきても、メニュータップ等のイベント領域は画面外に残ったままなのです

じゃあ、どうするかというと、Animationが終わったタイミング(AnimationListenerで拾えます)で、実際に隠しメニューの座標を画面内に変更する。
または、下から出てくるViewは演出のためのダミーと割り切って、実際にタップさせるViewは最初から画面内に配置しておいてHiddenにしておく、等の対応で行けると思います。
・・・“思います”と書いてるのは、まだ自分で実際にやってないからですが。。。


本日はこんな感じで。
しかし、週末というのに家でコーディングとか、やっぱワーカホリックかもしれませんねえ。。。