コンピュータクワガタ

かっぱのかっぱによるコンピュータ関連のサイトです

Androidアプリ入門 No.24 ListViewのイベント処理

ListView

ListViewのイベント処理

ここでは、ListViewのイベント処理を解説する。まず、choiceModeでsingleChoiceを指定した場合の値の取得を例にする。まず、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/listView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="#00f"
        android:dividerHeight="5px"
        android:choiceMode="singleChoice"
        />
</LinearLayout>

次に、strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello World, MainActivity!</string>
    <string name="app_name">ActivityTest</string>

    <string-array name="test_array">
        <item>あいうえお</item>
        <item>かきくけこ</item>
        <item>さしすせそ</item>
        <item>たちつてと</item>
        <item>なにぬねの</item>
        <item>はひふへほ</item>
        <item>まみむめも</item>
        <item>や ゆ よ</item>
        <item>らりるれろ</item>
        <item>わをん  </item>
    </string-array>
</resources>

ここまでは、今までと同様だが最後にMainActivity.javaを示す。OnItemClickListenerでListViewのClickのイベントを拾える。実際に処理するメソッドは、onItemClickだがこれに関しては後述する。今回は、ListView#getCheckedItemPositionメソッドでチェックされた位置を取得して表示している。

package sample.at;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ListView listView = (ListView) findViewById(R.id.listView);

        String[] aiueo = getResources().getStringArray(R.array.test_array);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_single_choice, aiueo);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Toast.makeText(getApplicationContext(),
                        (((ListView) parent).getCheckedItemPosition() + 1)
                        + "番目がチェックされました。", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

実行結果は以下。

次に、multipleChoiceの例を示す。strings.xmlは同じため書かない。まずは、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/listView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="#00f"
        android:dividerHeight="5px"
        android:choiceMode="multipleChoice"
        />
</LinearLayout>

次にMainActivity.javaを示す。複数選択の可能性があるため、チェックされている項目はListView#getCheckItemIdsで取得している。

package sample.at;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ListView listView = (ListView) findViewById(R.id.listView);

        String[] aiueo = getResources().getStringArray(R.array.test_array);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_multiple_choice, aiueo);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                long[] ids = ((ListView) parent).getCheckItemIds();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < ids.length; i++) {
                    if (i > 0) {
                        sb.append(",");
                    }
                    sb.append(ids[i]);
                }
                sb.append("がチェックされています。");
                Toast.makeText(getApplicationContext(), sb.toString(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

実行結果は以下。

次にListViewのどの項目が選択されたかのイベントを少し複雑な例で説明する。まず、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/listView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        />
</LinearLayout>

次に、list.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"
    >
    <TextView
        android:id="@+id/no"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#f00"
        android:textSize="16sp"
        />
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="30sp"
        />
</LinearLayout>

最後に、MainActivity.javaを以下に示す。

package sample.at;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        ListView listView = (ListView) findViewById(R.id.listView);
        SimpleAdapter adapter = new SimpleAdapter(this, getListData(), R.layout.list,
                new String[] { "no", "name" }, new int[] { R.id.no, R.id.name });
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                TextView textView = (TextView) ((LinearLayout) view).getChildAt(1);
                StringBuilder sb = new StringBuilder();
                sb.append("parent=").append(parent.getClass().getSimpleName())
                        .append(" position=").append(position)
                        .append(" id=").append(id).append(" textView.getText()=")
                        .append(textView.getText());
                Toast.makeText(getApplicationContext(), sb.toString(),
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

    private List<Map<String, String>> getListData() {
        List<Map<String, String>> listData = new ArrayList<Map<String, String>>();

        listData.add(getMapData(new String[][] { { "no", "01" }, { "name", "あいうえお" } }));
        listData.add(getMapData(new String[][] { { "no", "02" }, { "name", "かきくけこ" } }));
        listData.add(getMapData(new String[][] { { "no", "03" }, { "name", "さしすせそ" } }));
        listData.add(getMapData(new String[][] { { "no", "04" }, { "name", "たちつてと" } }));
        listData.add(getMapData(new String[][] { { "no", "05" }, { "name", "なにぬねの" } }));
        listData.add(getMapData(new String[][] { { "no", "06" }, { "name", "はひふへほ" } }));
        listData.add(getMapData(new String[][] { { "no", "07" }, { "name", "まみむめも" } }));
        listData.add(getMapData(new String[][] { { "no", "08" }, { "name", "や ゆ よ" } }));
        listData.add(getMapData(new String[][] { { "no", "09" }, { "name", "らりるれろ" } }));
        listData.add(getMapData(new String[][] { { "no", "10" }, { "name", "わをん  " } }));

        return listData;
    }

    private Map<String, String> getMapData(String[][] values) {
        Map<String, String> map = new HashMap<String, String>();
        for (int i = 0; i < values.length; i++) {
            map.put(values[i][0], values[i][1]);
        }

        return map;
    }
}

実行結果は以下となる。

ListViewのいずれかのItemのクリックはOnItemClickListenerで受け取ることができる。実際に呼び出されるメソッドの定義は複雑で、以下となる。

void onItemClick(AdapterView<?> parent, View view, int position, long id)
引数 説明
parent クリックされたAdapterのビューとなる。要するにListViewを取得できる。
view 実際にクリックされたビュー。
position アダプターの何番目がクリックされたか。
id クリックされた列のid。