Activity にタッチイベントが流れてくるまで
前回は View のヒエラルキーのなかをどうやってタッチイベントが伝搬するかを追いました。
参考にした資料には、 Activity#dispatchTouchEvent() からイベントが始まるとありますが、折角なのでそこまではどうなっているかも確認します。
先に概要としてまとめてしまうとこんな雰囲気でした。
View システムの根っこの部分をきちんと理解できてないので、勘違いがあるかもしれません。 (親子関係が特に怪しい)
前回は View のヒエラルキーのなかをどうやってタッチイベントが伝搬するかを追いました。
参考にした資料には、 Activity#dispatchTouchEvent() からイベントが始まるとありますが、折角なのでそこまではどうなっているかも確認します。
先に概要としてまとめてしまうとこんな雰囲気でした。
View システムの根っこの部分をきちんと理解できてないので、勘違いがあるかもしれません。 (親子関係が特に怪しい)
Android で独自定義のカスタムアニメーションを作りたかったので試してみたところ、 Animation クラスを継承して割と簡単に作れたのでメモ。
ここでは例として、 View を円周に沿って動かすようなアニメーションを作ってみました。
アニメーションさせたい View に対して中心点を指定して、開始角度と終了角度を与えてアニメーションさせてみます。
1 2 3 4 5 6 7 8 9 10 11 |
|
Android のバージョンは同じなのに、端末によってファイルの移動(renameTo())に失敗してしまうことがあって悩まされたが、オチは移動先のファイル名にクエスチョンマーク(“?”)が含まれていたことが原因だった。
クエスチョンマークが入ってしまっていたこと自体がバグだったのだけれど、そもそも何で端末によってこのようなことが起きるのかを軽く追ってみた。
成功する端末では内部ストレージに書き込みを行っており、失敗する端末では外部ストレージに書き込みを行っていた。
ファイルシステムを見てみると、内部ストレージは FUSE でマウントされているのに対し、外部ストレージは VFAT でマウントされていた。
1 2 3 4 5 |
|
正式な出典が見つからなかったけれど、 VFAT ではファイル名に以下の文字の使用を禁止しているようなので、恐らくこれが原因っぽい。
試しにその他の記号を含めたファイル名を作成してみたところ、全て失敗した。
1
|
|
参考 : ファイル名とフォルダ名で使用できない文字
というわけで、環境によって(サンプル数は少ないが、恐らく外部SDカードでは)一部の記号がファイル名に使えなくなることがある、ということが分かった。
Android のファイルシステム周りについては全く調べられていないが、いくつか気になることがあったのでメモ。
ListView の要素が無い場合に表示する View を指定できる setEmptyView() だが、その名前から想像できるのとは少し違う動きをする。
実際の動作は setEmptyView() で指定した View と ListView の Visibility を View.GONE と View.VISIBLE で入れ替えるだけとなっている。
そのため、 inflate() しただけでどこにも addView() していない View などを setEmptyView() で指定しても表示されないし、 ListView の子として表示される Header や Footer も表示されないこととなる。
通常は ListView と同階層に兄弟 View として xml に定義しておくのがよさそう。
EmptyView として設定する View の Visibility は特に指定しなくても ListView 側でやってくれるので問題ないです。
1 2 3 4 5 6 7 |
|
1 2 |
|
以下は実装箇所の確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
タッチイベントがうまく流れてこなくて困ったり、自力でイベントをルーティングしたりするときに困ったりと、ちょこちょことタッチイベントについて勉強したのでまとめておきます。
主にタッチイベントがどう流れてどう止まるかなどについて調べています。
イベントの流れを理解するには以下の資料がかなり参考になりました。
毎度のことながら、間違いがありましたらご指摘頂ければ幸いです。
Octopress ルートディレクトリの _config.xml の disqus_short_name に short_name を書き込むだけで Disqus と連携されてコメントモジュールが表示される。
1
|
|
ところが以下のエラーが表示されてしまい、コメントモジュールがロードされない。
1
|
|
オチは Disqus の short_name を理解していなかったのが原因で、ずっと Disqus ID を disqus_short_name に書き込んでいたのが問題だった。 # Disqus 使ったこと無かった上に説明を読んでなかった
Disqus では、コメントを投稿する単位としてまず Site を登録する必要があり、この Site の識別子として使われるのが short_name だった。 Disqus にログインした状態でここにアクセスして Site を登録したところ、無事に short_name が生成された。
Java において StackTrace を取得する。
どこかに仕込んでおくとデバッグ時に何かと便利。
1 2 3 4 5 6 7 8 9 |
|
FrameLayout で onDraw() のタイミングで処理をしたいが、どうも onDraw() が呼ばれないように見える。
確認したところ、 ViewGroup を継承したクラスは onDraw() の代わり dispatchDraw() が呼ばれるようだった。
(その名の通り子の View に対して draw() をコールしたりしなかったりするメソッド)
ViewGroup を継承したクラスに対して onDraw() のタイミングで実行したい処理は、 dispatchDraw() に書けば問題なさそう。
1 2 3 4 5 6 7 |
|
今まで気がつかなかったけれど、わざわざ generate してから preview しなくても、 preview 中に source ファイルを書き換えれば勝手にそれを検知して regenerate してくれるっぽい。
1 2 3 4 5 |
|
これは便利!
ちなみに新規ファイルを保存してもきちんと捕足して regenerate してくれるみたい。
投稿のハードルを限りなく低くしたいと思っている身からは、preview を立てっぱなしに出来るのは捗りそう。
今まで ImageView#getImageMatrix() で取得した Matrix のインスタンスに対して、直接 post*() のメソッドを呼んだりして操作すれば表示に反映されていたが、どうやら 4.3 で挙動が変わったご様子。
結論から言うと、横着せずにちゃんと毎回 setImageMatrix() をしてやるか、はじめに setImageMatrix() してから getImageMatrix() を使うようにすれば想定通りに動作する。
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 8 |
|
4.2 以前では mMatrix (initImageView()で初期化されてる)がそのまま返っているのに対して、 4.3 以降では mDrawMatrix が返るようになっている。 (mDrawMatrix は configureBounds() でセットされている)
mDrawMatrix がセットされていない状態だと、その場で Matrix のインスタンスが作られているため、このインスタンスに対して直接操作を行っても反映されないというわけでした。
1 2 3 |
|
1 2 3 4 5 6 |
|
Android はマイナーバージョンアップでも、結構こういう細かい挙動変更が入ってくるので、以前動いていたものが突然動かなくなることが良くあるのだけれど、Android のコードを直接見に行けば答えが書いてあるので安心感がありますね。