リスト表示(ListView)

(ブログ記事の一覧は「こちら」)

Androidに限らず、スマホアプリでよく見られる、リスト表示(ListView)の方法について学びます。

ここで学ぶこと

  • ListViewの使い方
  • Adapterについて
  • リストの各Viewの項目の設定

例題1

作成するもの

最もシンプルなリスト表示を作成します。

f:id:MJeeeey:20190902025600p:plain:w240

レイアウト

ListViewを全画面に配置します。

<?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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

プログラム

ListViewの項目を表示するには、Adapter(というAndroid特有のもの)を用います。Adapterとは、データをListViewの各Viewに渡す役割を持つものです。

例ではAdapterを継承したArrayAdapterを使用します。
android.R.layout.simple_list_item_1」はあらかじめ用意されているレイアウトファイルで、最もシンプルなプログラムでリスト表示が実現できます。

String[] strItems = { "北海道", "東北", "関東", "中部", "近畿", "中国", "四国", "九州" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strItems);

ListView listView = findViewById(R.id.listView);
listView.setAdapter(adapter);

実行、確認

ListViewの各Viewに、Adapterで指定した配列の各文字列が表示されます。

例題2

作成するもの

次に、独自のリスト表示を行う方法を確認していきます。下図のように、各Viewの右端にもテキストを追加します。

f:id:MJeeeey:20190905225225p:plain:w240

レイアウト

独自のリスト表示を行うということは、ListViewの各Viewについてレイアウトを用意する必要があります。
テキストエディタで以下のレイアウトを「list_item.xml」として作成します。(「activity_main.xml」と同じ場所に置いてください。)
以下の例では、TextViewを水平に並べた簡易なものとしました。

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

    <TextView
        android:id="@+id/textView_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>

    <TextView
        android:id="@+id/textView_detail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

プログラム

onCreate関数内は以下のように修正します。後で説明する、独自のAdapterItemクラスと、ArrayAdapterを継承した独自のMyAdapterを使用します。

private List<AdapterItem> mItems = new ArrayList<AdapterItem>();

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

    String[] strTitles = { "北海道", "東北", "関東", "中部", "近畿", "中国", "四国", "九州" };
    String[] strDetails = { "1道", "6県", "1都6県", "9県", "2府5県", "5県", "4県", "8県" };

    for (int i = 0; i < strTitles.length; i++) {
        AdapterItem item = new AdapterItem(strTitles[i], strDetails[i]);
        mItems.add(item);
    }

    ListView listView = findViewById(R.id.listView);
    listView.setAdapter(new MyAdapter(this, mItems));
}

onCreate関数の外に、AdapterItemクラスとMyAdapterクラスを定義します。
getView関数で、各Viewを「list_item.xml」で定義したものに合わせてデータをコントロールにセットします。

private class AdapterItem {
    String title;
    String detail;

    public AdapterItem(String title, String detail) {
        this.title = title;
        this.detail = detail;
    }
}

private class MyAdapter extends ArrayAdapter<AdapterItem> {

    private Context mContext = null;

    public MyAdapter(@NonNull Context context, List<AdapterItem> items) {
        super(context, -1, items);

        mContext = context;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View view;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.list_item, parent, false);
        } else {
            view = convertView;
        }

        AdapterItem adapterItem = getItem(position);

        TextView textViewTitle = view.findViewById(R.id.textView_title);
        textViewTitle.setText(adapterItem.title);

        TextView textViewDetail = view.findViewById(R.id.textView_detail);
        textViewDetail.setText(adapterItem.detail);

        return view;
    }
}

初めてこのプログラムを行うときは難しいと感じるかと思いますが、まずはこちらのプログラムをそのまま参考にしてもらって、他の場面で試しながら理解していくので良いと思います。

実行、確認

ListViewの各Viewに、独自のMyAdapterで設定したデータが表示されます。

課題1

例題1をもとに、リストの項目をクリックして、項目のテキストをToastで表示されるように修正してください。

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //
    }
});

課題2

例題2をもとに、リストの項目に画像を追加してください。

[ヒント]

  • 表示したい画像ファイル(.png)を追加しする。(app / src / main / res / rawフォルダを作成して、rawフォルダに画像を置く)
  • 「list_item.xml」にImageViewを追加する。
  • AdapterItemクラスにImageViewを追加する。
  • MyAdapterクラス内のgetView関数に、ImageViewを表示するプログラムを追加する。