プログラマになる

組み込みエンジニアで主にC言語、時々C#をやっている人の技術メモです。最近はAndroidも少しずつ勉強中

今更ながらListViewをまとめる - 基礎編 -

はじめに

今更ながらListViewの使い方をまとめたいと思います。
今回はPersonクラスを生成してそのプロパティをListViewに表示してみます。

1. ListViewに表示するItemを作成

まずはPersonクラスを定義します。

Person.kt

class Person(firstName : String, lastName : String, age : Int) {
    val firstName : String = firstName
    val lastName : String = lastName
    val age : Int = age
}

Personクラスを表示するためのLayoutを作成します。
今回は単純にPersonクラスを表示するものしてみました。

📝 simple_list_item1など標準で用意されているものもありますが今回は用途と合わないので独自で定義します。

list_item.xml

f:id:kaleidot725:20180624162651p:plain

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/personItem"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <TextView
        android:id="@+id/firstName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="firstName"
        android:background="#FF9999"/>

    <TextView
        android:id="@+id/lastName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="lastName"
        android:background="#99FF99"/>

    <TextView
        android:id="@+id/age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="age"
        android:background="#9999FF"/>
</LinearLayout>

2.ListViewのAdapterを作成する

list_item.xmlをViewとして生成するためにAdapterを作成します。
以下のようにArrayAdapterを継承したListViewAdapterを作成します。

ListViewAdapter

// コンストラクタで予め、表示したいPersonのリストを指定する。
class ListViewAdapter(fragmentActivity: FragmentActivity?, resource : Int, list: List<Person>) : ArrayAdapter<Person>(fragmentActivity, resource, list) {
    private val inflater : LayoutInflater = LayoutInflater.from(context)

    // ListViewによってViewが必要なときに呼び出される、なのでViewを生成して返してあげる
    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        // Viewを生成して、Adapterのコンストラクタから渡されたPersonListの要素をセットする
        val view = inflater.inflate(R.layout.list_item, parent, false)

        // 生成したViewからTextViewを取得する
        val firstNameTextView = view.findViewById<TextView>(R.id.firstName)
        val lastNameTextView = view.findViewById<TextView>(R.id.lastName)
        val ageTextView = view.findViewById<TextView>(R.id.age)

        // Personリストから値を取得し、セットする
        firstNameTextView.text = super.getItem(position).firstName
        lastNameTextView.text = super.getItem(position).lastName
        ageTextView.text = super.getItem(position).age.toString()

        return view
    }
}

3.ListViewを作成する

そしていよいよ最後です。
FramgentのLayoutにListViewを追加し表示できるようにします。

fragment_list_view.xml

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

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

次にFragmentのsrcに表示するPersonを生成してListViewにセットします。

ListViewFragment

📝ListView.adapterにListViewAdapterを渡しておく 📝ListViewは渡されたListViewAdapterを使ってViewを生成するのでitem_list.xmlのViewがListに表示される

class ListViewFragment : Fragment() {
    // 表示するリスト生成する
    val values : List<Person> = mutableListOf(
        Person("Mike",   "Ryan", 15),      Person("Fred",   "Griffin", 20), 
        Person("Ruke",   "Mohammed", 30),  Person("ふじい",  "まきこ", 40),
        Person("あずま",  "りさ" , 31),      Person("りゅう",  "ふみえ" , 32),
        Person("とりうみ","のりこ" , 34),     Person("はすみ",  "ちづる" , 46),
        Person("もりたに","かおり" , 25),     Person("すがわら","けいすけ" , 36),
        Person("すみよし","たつや" , 40),     Person("かつやま","まさのり" , 33),
        Person("させ",   "まさあき" , 27),    Person("ふない",    "ゆうすけ" , 35),
        Person("じんぐうじ", "ただゆき" , 36), Person("かねひら",   "ともはる" , 25),
        Person("おぶち",     "こうじ" , 24),  Person("あいやま",   "やすゆき" , 18))

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_list_view, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        // PersonリストをセットするListViewを取得する
        val listView = view.findViewById<ListView>(R.id.ListView)
      
        // ListViewAdapterを生成して、そのときにvaluesを引数として渡す
        listView.adapter = ListViewAdapter(activity, R.layout.list_item, values)
    }
}

さいごに

エミュレータで動かすとこんな感じに動きます。
結構スムーズに動作しているように見えますが実機で動かすとカクカクします。

ここでViewHolderを実装する必要性が出てきます。
ViewHolderはListに表示する数が多くなったときのパフォーマンスを改善する手法です。
次回はViewHolderについてまとめたいと思います。

f:id:kaleidot725:20180624163746g:plain

github.com