有山と申します。
検証用のコードを拝見して、現象を確認しました。
バージョンによってinvalidate()での描画の挙動が異なる現象には、ハード
ウェアアクセラレーションの有効無効が影響しているものと思われます。
試しに、AndroidManifest.xmlに、hardwareAccelerated="false"を追加する
と、invalidate()のタイミングで全ての子ビューが再描画されるようになりました。
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:hardwareAccelerated="false"
>
ハードウェアアクセラレーションは、API Level 11(Honeycomb)から導入され
ました。API Level 14(ICS)以降は、標準で有効の状態に設定されています。
AndroidManifestでtargetSdkVersionを、導入以前のバージョンにすると、標
準で無効になるので、全てが同じ挙動で動作するようになるということです。
詳細な記述は下記のリンクを参考にして下さい。
『ハードウェアアクセラレーションによる描画モデルは、本当に再描画が必要
(DIRTY)な部分のみを描画する』との記述があります。
Hardware Acceleration - Hardware accelerated drawing model
http://developer.android.com/guide/topics/graphics/hardware-accel.html#hardware-model
(1/28/13 9:43 AM), Masamichi Yoshii wrote:
> 初めまして。吉井と申します。
>
> LinearLayout の
> invalidate()メソッドを呼び出した場合、配下の全ての子Viewを再描画してくれると思っていたのですが、これがどうもこれがうまく動かないケースがありました。いろいろ試してみたところ、どうも機種によって動きが違うようです。
>
> Xperia SO-01B (Android2.3.3) --- 再描画する
> AquosPhone SH-01D (Android4.0.4) --- 再描画しない
> Nexus7 (Android4.2.1) --- 再描画しない
>
>
> この結果を見るり、4.xで動きが変わったようにも見えます。そこでエミュレータで確認してみたところ、不思議なことにこちらはどんなバージョンでもちゃんと子Viewを再描画してくれました。(2.1,
> 2.3.3, 3.2, 4.1.2, 4.2 で確認)
>
> 更にもう一つ分かったのは、上の結果は全て targetSdkVersion="16" で確認していましたが、これを
> targetSdkVersion="10" (Android2.3.3)にすると、どの機種でも再描画してくれるようになりました。
>
> 確認方法は、親の invalidate() を呼び出し、子Viewの onDraw() が呼び出されるかどうかをチェックしました。確認コードを
> Github に置いておきました。
>
>
https://github.com/masamichi441/AndroidInvalidateTest/blob/master/src/com/example/android/test/MainActivity.java
>
> invalidate()はもともとViewのメソッドであり、ViewGroupでもオーバーライドしていないようなので、子Viewに関しては関知しないよというのであれば、まあそれはそれで納得もできるのですが、実際にバージョンや機種によって(またはエミュレータ環境では)子Viewの再描画もしているので、どうにもすっきりしません。
>
> どなたかこの辺り、ご存じの方は教えてください。
>
--
Keiji,
ml_an...@c-lis.co.jp