前置き
ソース内で用意したアイテムのListをView側に用意したListViewに渡して表示するだけの
簡単な処理を作ります
作る物
下記のListViewを表示するだけのActivityを作ります
人選は、個人的にホットな奴らを採用してます
別にちびまる子ちゃんの登場人物とかでもいいです
なんでLegacy
なんでか知らんけど、分類がLegacyになってた
Legacyって書いてあるから、今後の追加機能とかは望めないけど
消したら影響受けるアプリも多そうだし、残り続けはするんじゃないかなと予想
軽く調べた限りでは、移行先候補として「RecyclerView」があるらしい
使った事ないので、説明だけで判断すると
「表示領域外に移動したアイテムを再利用する」とか
ゲームとかで大量のアイテムをスクロールメニューに表示したいときに使えそうだね
まぁ、ゲーム作るならAndroid直に触るよりもUnityとかUnrealEngine使うわって話になるけど
プロジェクト作成
例によって「Empty Activity」でプロジェクト作成
パッケージ名とプロジェクト名はなんでもいいが、筆者は
パッケージ名:com.arrayadapter.arrayadaptertest
プロジェクト名:ArrayAdapterTest
にした
test_list_item_header.xmlは最後のほうで語る「おまけ」で使うので
今の所は無いものとして扱ってください
build.gradle(app)
Android セクションに下記を追加
buildFeatures {
dataBinding = true
}
main_activity.xml
HelloWorld消して、空っぽのListViewを置くだけ
ソース側で引っ張ってこれるようにIDも付与する
<?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">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</androidx.constraintlayout.widget.ConstraintLayout>
test_list_item.xml
ListViewに表示する1行分のアイテムの
見た目やバインディング情報を定義する
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="li"
type="com.arrayadapter.arrayadaptertest.TestListItem" />
</data>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/name"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="@{li.name}"/>
<TextView
android:id="@+id/gender"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="@{li.gender}"/>
<TextView
android:id="@+id/age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Integer.toString(li.age)}"/>
</LinearLayout>
</layout>
後述で作る「TestListItem」の名前を、このxml内部で「li」と命名し
セットした3つのTextViewそれぞれにバインディングするだけのxml
最初のrootを「layout」で宣言したため、ビルドすれば
com.arrayadapter.arayadaptertest.databinding パッケージが自動生成され
そこに「TestListItemBinding」クラスが自動生成される
TestListItem.kt
ListViewにぶち込むアイテム1個分の情報
package com.arrayadapter.arrayadaptertest
class TestListItem (val name : String , val gender : String , val age : Int ){
}
余談だが、これだけで、Javaで言う、下みたいな事を書いた事になるらしい
public class TestListArray {
public string name;
public string gender;
public string age;
public TestListArray ( string _name , string _gender , int _age )
{
name = _name;
gender = _gender;
age = _age;
}
}
いやぁ、便利っすねぇ~ Kotlin
TestListAdapter.kt
こいつが重要
View側のListViewとソースを結び付ける中継役と思えばいい
たぶんもっといろんなことができそうな気がする
package com.arrayadapter.arrayadaptertest
import android.content.Context
import android.view.LayoutInflater
import android.widget.ArrayAdapter
import android.view.View
import android.view.ViewGroup
import com.arrayadapter.arrayadaptertest.databinding.TestListItemBinding
class TestListAdapter(context: Context, objects: List<TestListItem>) :
ArrayAdapter<TestListItem>(context, 0, objects) {
private lateinit var iLayoutInflater : LayoutInflater
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
iLayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
// test_list_item.xmlのバインディングデータ取得
var binding = TestListItemBinding.inflate(iLayoutInflater)
// test_list_item.xmlのli変数とbindさせる
val li : TestListItem = getItem(position)!!
binding.li = li
return binding.root
}
}
重要なのはgetView関数の実装
TestListAdapterの生成時にListが渡されて、すでにListを持っているため、
getView関数が実行されたときに、引数で渡されたpositionが示すlistのTestListItemを取得し
それを「test_list_item.xml」内部で定義した「li」とバインドさせてバインディングを行う
MainActivity.kt
まずはソース全文
package com.arrayadapter.arrayadaptertest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ListView;
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// listviewの参照を取得
var listView : ListView = findViewById(R.id.list_view) as ListView
// 仮データ作成
var list : MutableList<TestListItem> = mutableListOf(
TestListItem("田所浩二" , "ホモ" , 24 ),
TestListItem("長谷川亮太" , "男" , 810 ),
TestListItem("唐澤貴洋" , "男" , 1000000 ),
TestListItem("岩間好一" , "男" , 931 ),
)
// リストを自動的に構築するための必要な処理や情報をセット
var adapter : TestListAdapter = TestListAdapter(this,list)
listView.adapter = adapter
}
}
//仮データ作成 の所は、お好みの男児や美少女とかを好きなだけ追加していい
重要なのは
// リストを自動的に構築するための必要な処理や情報をセット
var adapter : TestListAdapter = TestListAdapter(this,list)
listView.adapter = adapter
この部分で、用意したlistを元にAdapterを生成し
listViewが持つAdapterと関連付ける
これによって、listViewの内容がソース内で設定したList通りに表示される
ビルドしてみよう
成功すれば、愉快な仲間たちがList形式で表示されたAcitivityが起動するはず
課題
ソース部分にいろいろごちゃごちゃ書きすぎてるので
XMLの記述でうまく吸収できないか
参考
おまけ
ヘッダーをつけてみよう
リスト自体は表示できたけど、項目名が表示されてなくて、なんかイケてないので
ヘッダーをつけてみる事にする
ヘッダー表示用の「test_list_item_header.xml」を用意する
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/name"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="Name"
android:background="#000000"
android:textColor="#FFFFFF"/>
<TextView
android:id="@+id/gender"
android:layout_width="70dp"
android:layout_height="wrap_content"
android:text="Gender"
android:background="#000000"
android:textColor="#FFFFFF"/>
<TextView
android:id="@+id/age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Age"
android:background="#000000"
android:textColor="#FFFFFF"/>
</LinearLayout>
</layout>
ヘッダーと項目アイテムが別個になってるのが確認できるように
ヘッダーの背景色を黒、文字色を白に適当に設定
MainActivity.ktに3行追加する
package com.arrayadapter.arrayadaptertest
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ListView;
import com.arrayadapter.arrayadaptertest.databinding.TestListItemHeaderBinding //追加
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// listviewの参照を取得
var listView : ListView = findViewById(R.id.list_view) as ListView
// ヘッダーをセットする
val testListItemHeaderBinding = TestListItemHeaderBinding.inflate(layoutInflater) //追加
listView.addHeaderView(testListItemHeaderBinding.root) // 追加
// 仮データ作成
var list : MutableList<TestListItem> = mutableListOf(
TestListItem("田所浩二" , "ホモ" , 24 ),
TestListItem("長谷川亮太" , "男" , 810 ),
TestListItem("唐澤貴洋" , "男" , 1000000 ),
TestListItem("岩間好一" , "男" , 931 ),
)
// リストを自動的に構築するための必要な処理や情報をセット
var adapter : TestListAdapter = TestListAdapter(this,list)
listView.adapter = adapter
}
}
もっと奇麗なやり方がありそうだが、手っ取り早く思いついた方法はこれ
ビルドしてみよう
成功すれば、以下のように表示されるはず
参考