[Android] ListViewのlayoutをwrap_contentで指定しない
今回、ふとしたことで気づいたので備忘録としてまとめます。
ListViewのlayoutをwrap_contentで指定するとどうなるか。
まずは、簡単なコードでListViewのlayoutをwrap_contentで指定してみます。
layoutファイル activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ListView android:id="@+id/ListView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
続いて、文字列のリストをListViewにセットします。
MainActivity.java
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); List<String> objectList = new ArrayList<String>(); for (int i = 0; i < 10; i++) { objectList.add("title" + i); } ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, android.R.id.text1, objectList); ListView listView = (ListView) findViewById(R.id.ListView); listView.setAdapter(adapter); } }
これで実行すると以下のような文字列のリストが表示できました。
しっかり表示されているので、OKですね。めでたしめでたし。。。。
と、思っていた時期もありました。(さっきまで)
MainActivity内のArrayAdapterを少し改良してログを見てみます。
MainActivity.java
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); List<String> objectList = new ArrayList<String>(); for (int i = 0; i < 10; i++) { objectList.add("title" + i); } CustomAdapter adapter = new CustomAdapter(getApplicationContext(), android.R.layout.simple_list_item_1, android.R.id.text1, objectList); ListView listView = (ListView) findViewById(R.id.ListView); listView.setAdapter(adapter); } class CustomAdapter extends ArrayAdapter<String> { public CustomAdapter(Context context, int resource, int textViewResourceId, List<String> objects) { super(context, resource, textViewResourceId, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { Log.d("getView","position:" + position); return super.getView(position, convertView, parent); } } }
上記のように修正して、実行してみます。すると以下のようなログが出力されました。
なんか知らない間にgetViewめっちゃ呼ばれてるやん! と、なります。
続いて、ListViewのlayoutをmatch_parentにしてみると...
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <ListView android:id="@+id/ListView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
これで実行し、ログを確認してみます。
ちゃんと1回ずつ呼ばれてるやん! と、なります。
wrap_contentでは仮想的に何度も描画することがあるらしいので、その辺の関係でしょうか。
特に見た目などには変化はないですが、無駄とわかれば避けたほうがいいと思うので、極力match_parentで構築したいですね。
以上です