Taka blog

プログラミングとか

[AndroidStudilo4]ListViewの使い方

リスト形式で表示するには、ListViewかRecyclerViewを用います。RecyclerViewはListviewをより柔軟にしたものなので、今回はListViewをご紹介します。

ListViewのレイアウト

リスト全体のレイアウトは、ListView内で定義できます。各アイテムのレイアウトは、別途定義するかデフォルトで用意されているものを使うことになります。

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="@color/gray"
    >

    <ListView
        android:id="@+id/itemList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:divider="@color/green"
        android:dividerHeight="4dp"
        >
    </ListView>

</LinearLayout>

LinearLayoutは、子要素を1列に並べるレイアウトです。これも各Layoutの中でシンプルな方です。

ListViewのdividerはアイテム間の色を、dividerHeightはアイテム間の高さを定義します。

ListViewにアイテムを表示する

MainActivity

@Override
protected void onResume() {
	super.onResume();

	// ListViewに表示したいデータ
	List<String> list = new ArrayList<String>();
	list.add("sample1");

	// データとレイアウト内のListviewを紐付け
	ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, list);
	ListView listView = (ListView)findViewById(R.id.itemList);
	listView.setAdapter(adapter);
}

ListViewにデータを設定するためには。Adapterが必要です。Adapterにも種類があるのですが、ArrayAdapterの場合はList型のデータを渡します。

ArrayAdapterの生成時、第2引数はリスト表示されるアイテムのレイアウト定義です。例ではAndroidStudioにデフォで用意されているレイアウトを指定しています。

流れは、List型データを作成 → データを引数にしてAdapter生成 → ListViewを画面レイアウトから生成 → ListViewにAdapterを追加 です。

Listviewにクリック時の操作を追加する

MainActivity

@Override
protected void onResume() {
	super.onResume();

	// 省略
	
	// クリック時の処理
	listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
		@Override
		public void onItemClick(AdapterView<?> parent, View view, int positon, long id) {
			// 例として、画面遷移処理を定義
			Intent intent = new Intent(MainActivity.this, SubActivity.class);
			startActivity(intent);
		}
	});
}

onItemClickの第3引数であるpositionには、クリックしたアイテムのindexが入ります。これを使って、アイテムの持つデータを更新したり、リストからアイテムを削除したりできます。

ListViewに長押し時の処理を追加する

contextMenuとsetOnItemLongClickListenerの2通りの方法があると思いますが、contextMenuの方を使います。

長押し時にcontextで表示されるボタンと、処理を定義します。

res/menu/context.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/context_del"
        android:title="Delete" />

</menu>

MainActivity

@Override
protected void onResume() {
	super.onResume();

	// 省略

	// listViewにcontextを設定
	registerForContextMenu(listView); 
}

// 利用するcontextを指定する
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) {
	super.onCreateContextMenu(menu, view, info);
	// 上のxmlを指定する
	getMenuInflater().inflate(R.menu.context, menu);
}

// contextのボタン押下時、対応する処理を実行する
@Override
public boolean onContextItemSelected(MenuItem item) {
	// 長押ししたアイテムのindex(position)を取得する
	AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
	int position= info.position;
	
	switch(item.getItemId()) {
		// xmlで定義したボタンに処理を割り当てる
		case R.id.context_del:
			Toast.makeText(this, "test del", Toast.LENGTH_LONG).show();
			break;
	}
	return false;
}

サンプルの処理では長押ししたアイテムの位置を利用はしていませんが、取得処理を載せています。

ListViewから要素を追加する/削除する

List型データの要素を追加または削除し、それをArrayAdapter経由でListViewに反映させる、という流れになります。

まずは、onContextItemSelectedからList型データとArrayAdapterを参照できるように、クラス変数で定義するようにコードを変更します。

public class MainActivity extends Activity {
	ArrayAdapter adapter;
	List<String> list;

前章のonContextItemSelectedを、以下のように書き換えます。

// contextのボタン押下時、対応する処理を実行する
@Override
public boolean onContextItemSelected(MenuItem item) {
	// 長押ししたアイテムのindex(position)を取得する
	AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
	int position= info.position;

	switch(item.getItemId()) {
		// xmlで定義したボタンに処理を割り当てる
		case R.id.context_del:
			list.remove(position);
			list.add("sample2");
			adapter.notifyDataSetChanged();
			break;
	}
	return false;
}