2012/03/02
ListView は Graphical Layout で作ったまま使ってはいけない
【Androidアプリ】AdapterのgetView()が必要以上に呼ばれる件|べっ、別にWeb言語のことなんか好きじゃないんだからねっ!!/// という記事によると、layout_width と layout_height が両方共 fill_parent じゃないと、この現象が起こるとのこと。
まさに、ご指摘の通り!
ListView の height が以下のように wrap_content になっていました。
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</ListView>
</LinearLayout>
これを、fill_parent にすることで無駄な動きはなくなりました。
以下がログです。
Inflate 0 (position: 0) 1167910792 Display (position: 0) 1167910792 Inflate 1 (position: 1) 1167915800 Display (position: 1) 1167915800 Inflate 2 (position: 2) 1167920008 Display (position: 2) 1167920008 Inflate 3 (position: 3) 1167924216 Display (position: 3) 1167924216 Inflate 4 (position: 4) 1167928480 Display (position: 4) 1167928480 Inflate 5 (position: 5) 1167932688 Display (position: 5) 1167932688 Inflate 6 (position: 6) 1167936896 Display (position: 6) 1167936896 Inflate 7 (position: 7) 1167941104 Display (position: 7) 1167941104 Inflate 8 (position: 8) 1167945312 Display (position: 8) 1167945312 Inflate 9 (position: 9) 1167949520 Display (position: 9) 1167949520 Inflate 10 (position: 10) 1167953728 Display (position: 10) 1167953728 Inflate 11 (position: 11) 1167957936 Display (position: 11) 1167957936
見事に直っていますね。
wrap_content だと、一度描画してみないと ListView 全体のサイズがわからない。
よって、全部(仮想的に)描画してサイズを測り、画面をはみ出ることを確認した後、もう一度描画する必要がある。ということだと思われます。
言われてみると確かにそうだー。
ただ、このレイアウト、 Graphical Layout ツールを使って書いたのです。
つまり、ドラッグアンドドロップで ListView を作成して、そのまま使っているとパフォーマンスがよろしくないですよ。って事ですね。
本当に wrap_content にしたい場合を除いて、fill_parent にしてあげましょう。(あ、最近だと match_parent ですね)
んー、気を付けなければ。
てか、既に結構やっちゃってるなー…
2012/3/3 追記
検証に使用したコードを GitHub で公開しました。
以下の要領で取得することができます。
以下の要領で取得することができます。
2013/10/29 追記
諸事情により、GitHub から Bitbucket に移動しました。
$ git clone https://kokufu@bitbucket.org/kokufu/ListViewExperiment.git $ cd ListViewExperiment $ git checkout 20120302
2 件のコメント:
listviewに表示される画像がどうしてもずれてしまって非同期処理時に起こる不具合だと思って、1日近く悩んでいましたが、原因がレイアウトだったとは。助かりました。
ありがとうございます!!
お役に立てたようで良かったです。
ただ、この Layout の問題はパフォーマンスの問題に関したものなので、「画像がどうしてもずれてしまって」の解決策にはならないような気がします。
「画像のずれ」の意味していることによるのですが、ListView をスクロールさせていった場合、同じような問題がおこったりしないでしょうか?
その場合は、以下の記事の方が参考になるかもしれません。
穀風: getView が呼ばれるタイミングと動作
コメントを投稿