ListView で表示リスト項目の無い場合のビューを指定する方法

前回の記事「ListView の基本的な使い方」で作成したプログラムを少し拡張してみましょう。

以前の記事では、ボタンを押すたびに ListView に表示するリスト項目(ここでは文字列)を追加していきましたが、表示するものが無い場合は何を表示すれば良いでしょうか?

せめて、「項目がありません」とか「ボタンを押してください」というメッセージでユーザーに対し、使い方を教えるような表示が出来たら便利かもしれませんね。

ListView には表示項目が空の場合に表示する View を指定する機能があります。

表示リスト項目が無い場合に表示する View を指定する setEmptyView

ここで作るプログラムの概要

前回のプログラムではプログラムを起動した直後は、アダプターに指定されているデータリストの中に項目がないために、ListView には何も表示されていませんでした。

しかし、今回は "No items Found" (項目が見つかりません) という文字が画面中央に表示されています。

画面下部の "Add" ボタンを押す度に、前回同様 "Hello!" という文字が追加され、それと同時に項目がみつかりませんという文字は非表示になります。

"Clear" ボタンを押すと項目はクリアされ、また "No items Found" という文字が表示されます。

これはどのようにすれば実装可能なのでしょうか。

実は ListView には Empty View (空の View) というものを指定する機能が実装されています。

今回はこの Empty View として、TextView を指定しています。

Empty View を指定する実装方法

早速 Empty View を指定するコードを見てみましょう。全体的には「ListView の基本的な使い方」と同様なので、ListView の概要やアダプターなどについてはそちらを参考にしてください。

主な変更点は Clear ボタンを追加した点と、setEmptyView メソッドを呼び出している箇所です。

package com.example.emptyviewtest1;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity
  implements OnClickListener {

  static final String TAG = "ListViewTest";
  
  ListView listView;
  Button addButton;
  Button clearButton;
  TextView emptyTextView;
  
  static List<String> dataList = new ArrayList<String>();
  static ArrayAdapter<String> adapter;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViews();    
    setListeners();
    setAdapters();
  }
  
  protected void findViews(){
    listView = (ListView)findViewById(R.id.listView1);
    addButton = (Button)findViewById(R.id.button1);
    clearButton = (Button)findViewById(R.id.button2);
    emptyTextView = (TextView)findViewById(R.id.emptyTextView);
    listView.setEmptyView(emptyTextView);
  }
  
  protected void setListeners(){
    addButton.setOnClickListener(this);
    clearButton.setOnClickListener(this);
  }
  
  @Override
  public void onClick(View v) {
    switch(v.getId()){
    case R.id.button1:
      addItem();
      break;
    case R.id.button2:
      clearItems();
      break;
    }
  }
  
  protected void setAdapters(){
    adapter = new ArrayAdapter<String>(
      this, 
      android.R.layout.simple_list_item_1, 
      dataList);
    listView.setAdapter(adapter);
  }
  
  protected void addItem(){
    adapter.add("Hello!");
  }
  
  protected void clearItems(){
    adapter.clear();
  }
}

レイアウトは次の通り。前回の例からの主な変更点は "No items found" という文字を表示する TextView を追加したことと、"Clear" ボタンを追加したところです。

<?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/emptyTextView"
    android:text="No items found"
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:layout_weight="1"
    android:textSize="20sp"
    android:gravity="center"/>
  <ListView 
    android:id="@+id/listView1" 
    android:layout_height="wrap_content" 
    android:layout_width="match_parent" 
    android:layout_weight="1"/>
  <LinearLayout 
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
  <Button 
    android:text="Add" 
    android:id="@+id/button1" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content"/>
  <Button 
    android:text="Clear" 
    android:id="@+id/button2" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content"/>
  
  </LinearLayout>
</LinearLayout>

アイテムが無い場合のビューを指定するのは、setEmptyView を呼び出す箇所に尽きます。これによって、データリストの中にアイテムが無い場合に、自動的に指定したビューが表示されます。

その他、Empty View とは直接関係ありませんが念のため説明すると、アイテムをデータリストからクリアする方法に少し注意が必要です。

ここではアダプターの clear() メソッドを呼び出しています。これによって、アダプターに関連付けされている ArrayList の要素が全て削除され、かつ、 ListView の表示も速やかに変更されています。

もし ArrayList の要素を直接 (アダプターを通さずに) 削除した場合は、その後アダプターの notifyDataSetChanged メソッドを呼ばないと、ListView に変更が通知されませんので、表示が変わりません。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Android 開発入門