ListViewとSimpleAdapter使い方

目次へ

ListViewとAdapter

ListViewは複数のデータを表示するのに使いやすい部品です。
データの一つ一つがひとつの項目からなるデータの場合にも、 データの一つが複数の項目からなり、2次元の表のような形になる場合にも使えます。
また、データ自体はAdapterクラスが管理し、Viewとの橋渡しを行います。

ここではSimpleAdapterを使ってListViewに表示させます。 SimpleAdapterを使うことにより、1つのデータの中に複数の項目が含まれていても 全てを簡単に表示できます。
データの型式は、ひとつのデータをMapで作成しそれをArrayListの中に入れていきます。 データがひとつの項目からなるような場合には、ArrayAdapterを使いもっと簡単に表示ができます。 この方法についてはこちらご覧ください。

ListViewとSimpleAdapterの使い方

手順

  • レイアウトファイル(例:activity_main.xml)にListViewを作成します
  • 1行分のデータをどのようなレイアウトで作成するかを示す レイアウトファイル(例:row.xml)を作成します
  • ListViewの1番上にタイトルをつけるなら タイトル用のレイアウトファイル(例:row_header.xml)を作成します
  • ArrayList<Map<String,Object>>の型式にしたデータを作成します
  • SimpleAdapterのインスタンスを作成し、
    • コンテキストと、
    • 1行分のレイアウトファイル(row.xml)と、
    • 各項目を、その中のどこに表示するか
    • データ全体
    を指定し、ListViewにこのインスタンスをセットします。
  • ListViewに表示されているデータを変更した場合には、データの変更だけではListViewの表示 が更新されないために、Adapterが持つnotifyDataSetChangedメソッドを呼び出します。
  • ListViewをタップした時のリスナは、AdapterView.OnItemClickListener、 長押しした時のリスナは、AdapterView.OnItemLongClickListenerですので、 必要なリスナを作成し、setOnItemClickListener、あるいはsetOnItemLongClickListener でListViewにセットします。
  • ListViewの1番上にタイトルをつけるには、addHeaderViewメソッドを使います。

activity_main.xmlの例

ListViewにセットされるデータの数が増えると、自動で縦のスクロールバーが表示されますが、項目数が多くなり、 横にはみ出す場合、横のスクロールバーは自動では表示されませんので、HorizontalScrollViewの中にListViewを いれることで、横のスクロールバーを表示しようとしています。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <Button
        android:id="@+id/addButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="データを追加する"
        android:layout_marginBottom="30dp"
        android:orientation="horizontal"
        app:layout_constraintBottom_toTopOf="@+id/listViewScroll"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <HorizontalScrollView
        android:id="@id/listViewScroll"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:padding="10dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/addButton">

        <ListView
            android:id="@+id/listView1"
           android:layout_marginBottom="50dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </HorizontalScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

row.xmlの例

1行分のデータを入れる場所を指定しているレイアウトファイルです。どのTextViewにどの項目を入れるかは SimpleAdapterのインスタンスを作るときに指定します。

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

    <TextView
        android:id="@+id/rowId"
        android:layout_width="120dp"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/rowTitle"
        android:layout_width="240dp"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/rowAuthor"
        android:layout_width="120dp"
        android:layout_height="wrap_content" />

 </LinearLayout>

row_header.xmlの例

ListViewの一番上につけるタイトルをここで、指定しています。

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

    <TextView
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:text="ID" />
    <TextView
        android:layout_width="240dp"
        android:layout_height="wrap_content"
        android:text="書名" />
    <TextView
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:text="著者名" />

</LinearLayout>

MainActivityの例

この中で、ListViewに表示するデータを作成し、SimpleAdapterを作成し、 ListViewにAdapterをセットます。
ListViewの項目を長押ししたときにはどのデータを長押ししたかを Toastで表示するリスナーをセットしています。
MainActivityクラスがAdapterView.OnItemLongClickListenerを実装しているため このクラスの中にonItemLongClickメソッドを作成しており、ListViewを長押しすると それが呼び出されるようになります。
また、ListViewの1番上には、各項目のタイトルをセットしています。

また、データを追加するボタンをタップしたときには、データを自動で追加し、 すぐに、それをListViewに表示しています。


import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity 
            implements AdapterView.OnItemLongClickListener{

    ListView listView;
    SimpleAdapter adapter;
    ArrayList<Map<String, Object>> list = 
            new ArrayList<Map<String, Object>>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //------------------------------- ListViewとSimpleAdapter
        listView = findViewById(R.id.listView1);
        View header = (View) getLayoutInflater().inflate
        		(R.layout.row_header, null);
        listView.addHeaderView(header);
        setData();	//データを自動で作成しlistに追加
        adapter = new SimpleAdapter(
                this,
                list,                            //ArrayList
                R.layout.row,                    //ListView内の1行分のレイアウト
                new String[]{"id", "title", "author"},    //1つのデータはmapに格納されているがその項目のキー
                new int[]{R.id.rowId, R.id.rowTitle, R.id.rowAuthor}  //キーに対してrow.xml内のどのidに表示するか
        );
        listView.setAdapter(adapter);    	//ListViewにAdapterをセット
        listView.setOnItemLongClickListener(this);	//長押しした時、MainActivityのonItemLongClickを呼び出す

        //------------------------------- データの追加
        Button addButton = findViewById(R.id.addButton);
        addButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                setData();                      //データを追加
                adapter.notifyDataSetChanged(); //ListViewの値が更新される
            }
        });
    }
    @Override
    public boolean onItemLongClick(AdapterView<?> adapterView, View view, 
    		int position, //positionは表題含めて0から始まる
        	long id) {	//idは表題含めず1行目が0から始まる
        
        Map curr = list.get((int)id);
        String str = "ID:"+curr.get("id") + " Title:" + 
                curr.get("title") + " Author:" + curr.get("author");
        Toast.makeText(this,str,Toast.LENGTH_LONG);

        return true;
    }
    //---------------テストデータ作成
    private void setData() {
        int size = list.size();
        for(int i=size+1; i<size+10; i++) {
            Map map = new HashMap();
            map.put("id",i);
            map.put("title", "初めてのAndroid"+i);
            map.put("author","作者"+i);
            list.add(map);
        }
    }
}

コメント

このブログの人気の投稿

ListViewの使い方

AsyncTaskについて