2010年08月04日

AndroidのListActivity

Android 開発を始めました。

ListView を使ってみようと思って調べてみると、大体 ListActivity を使って、、、という話が多いのですが、素朴な疑問として、そもそも ListActivity ってそんなメリットがあるの?というのが今回の話。

普通の Activity で ListView を使うようにコードを書くと以下のような感じ。
まず、おおもとのレイアウトとして、layout/main.xml を作成。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<ListView android:id="@+id/list" android:layout_width="wrap_content" 
  android:layout_height="wrap_content"></ListView>
</LinearLayout>
list の1行1行になる layout/col.xml を作成。
<?xml version="1.0" encoding="utf-8"?>
<TextView android:text="@+id/TextView01" android:id="@+id/TextView01" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  xmlns:android="http://schemas.android.com/apk/res/android"></TextView>
Activity は TestActivity クラスと名付けて以下のようにします。
public class TestActivity extends Activity {
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.main);
	    
	    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.col);
	    adapter.add("東京都");
	    adapter.add("神奈川県");
	    adapter.add("千葉県");

	    ListView listView = (ListView)this.findViewById(R.id.list);
	    listView.setAdapter(adapter);
    }
}
これで実行すると、問題なく表示されます。

では、ListActivity を使ってみましょう。
public class TestActivity extends ListActivity {
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.main);
	    
	    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.col);
	    adapter.add("東京都");
	    adapter.add("神奈川県");
	    adapter.add("千葉県");

	    setListAdapter(adapter);
    }
}
太字部分が変更したところです。
これで実行しようとすると、正常に起動できません。debug してみると、
Your content must have a ListView whose id attribute is 'android.R.id.list'
というエラーが表示されます。

ListActivity を使う場合、ListView の id は android.R.id.list にしないといけないのです。
具体的に言うと、main.xml を以下のようにする必要があります。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<ListView android:id="@id/android:list" android:layout_width="wrap_content" 
  android:layout_height="wrap_content"></ListView>
</LinearLayout>
@+id/list から @id/android:list に変更している点に注目してください。

Activity と ListActivity をそれぞれ拡張しましたが、違いとしては、 ListView をわざわざ findViewById() する必要がない程度でした。
わざわざコードを書かなくても、ListActivity のリファレンスを見ればわかるのですが。。。

ListActivity のソースを見ると分かりますが、
@Override
public void onContentChanged() {
    super.onContentChanged();
    View emptyView = findViewById(com.android.internal.R.id.empty);
    mList = (ListView)findViewById(com.android.internal.R.id.list);
    if (mList == null) {
        throw new RuntimeException(
                "Your content must have a ListView whose id attribute is " +
                "'android.R.id.list'");
    }
と ListActivity の中で、com.android.internal.R.id.list を取得していることが分かります。
ListActivity では、@id/android:list を決め打ちすることで、ListView をわざわざ findViewById() せずに済むようになっているという話ですね。
posted by おちエン at 01:26| Comment(3) | Android | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
以下エラーについて、困っていたところ辿り着きました。
Your content must have a ListView whose id attribute is 'android.R.id.list'

大変助かりました。ありがとうございました。
Posted by at 2013年04月18日 16:21
大変ためになりました。
ずっと迷っていたことを
解決できました(^^)/
ありがとうございます!!
Posted by 匿名 at 2013年09月10日 14:03
今までずっとActivityを継承して作成していました。
目立った利点はないようなのでListActivityは使わなくてもいいかなと思い始めました。
Posted by at 2014年07月13日 21:15
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。