SimpleAdapter
参考1: 研修2日目
参考2: SimpleAdapter
MutableList<MutableMap<String, *>>
型のデータ構造をとるAdapter
クラス。
MutableList
「キー
と値
をもち、要素数が可変
」なMutableMap<String, *>
型のデータを、各インデックス
に格納したリスト
。
SimpleAdapterの生成
定義
SimpleAdapter(
context: Context!,
data: MutableList<out MutableMap<String!, *>!>!,
resource: Int
from: Array<String>!
to: IntArray!
)
// パラメータ
// context: コンテキストとなるアクティビティオブジェクト
// data: リスト形式ビューに反映するリストデータ
// resource: リスト形式ビューの各Itemのレイアウトを表現するR値
// from: MutableMapのキーのみを格納した配列
// to: Item内の複数のビュー(=TextView)を識別するR値(=ID)を格納した配列
// -> toで指定したビュー(=TextView)に対して、
// fromで指定したキーに対応する値を格納
値を加工して表示するListView
// 発展: 値を加工したListViewの生成
class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
val nameList = createNameList()
val from = arrayOf("name", "sex")
val to = intArrayOf(R.id.tvName, R.id.imSex)
// Adapterオブジェクトの生成
val adapter = SimpleAdapter(
applicationContext,
nameList,
R.layout.row,
from,
to
)
// AdapterにViewBinderオブジェクトをセット
adapter.viewBinder = CustomViewBinder()
// リストデータを紐づけるListViewの定義
val lvPhones = findViewById<ListView>(R.id.lvNameList)
// ListViewにAdapterオブジェクトをセット
lvPhones.adapter = adapter
}
// 加工するリストデータを生成するメソッド
private fun createNameList(): MutableList<MutableMap<String, Any>> {
// 加工するリストデータを記述
... // 最終的に"return <リストデータ>"を記述
}
// MutableMapの値を基にデータを加工するクラス
private inner class CustomViewBinder: SimpleAdapter.ViewBinder {
// MutableMapの値を基にデータを加工
// -> ListView生成時に自動的に実行される
override fun setViewValue(
view: View,
data: Any,
textRepresentation: String
): Boolean {
// データの加工処理
... // 最終的に"return true/false"を記述
// true: データのバインドが実行された場合
// false: データのバインドが実行されなかった場合
}
}
}
画面の追加
参考: 研修1日目
アプリに表示される文字列
を除き、アプリの1画面
を構成しているのは、以下の3つ。
- アプリ内処理を担う、
app/java
フォルダのアクティビティクラス
(=.kt
ファイル)- 画面構成を担う、
app/res/layout
フォルダのレイアウトファイル
(=.xml
ファイル)- 1.および2.を認識する、
app/manifests
フォルダのAndroidManifest.xml
ファイル
画面を追加する場合は、AndroidManifest.xml
ファイルにactivity
タグを記述する必要がある。
※Android Studio
は、New Activity
の作成時に、アクティビティ
の追加にあたって必要な処理を自動的に行う。
Androidにおける画面遷移
遷移先
の画面は、遷移元
の画面の前面に表示される。
遷移先から戻る場合は、遷移先
の画面が消滅し、背面に隠れていた遷移元
の画面が表示される挙動をとる。
インテント(Intent)
参考: インテント
参考2: インテントのクラスメソッド
画面遷移
にあたり、画面
(=アクティビティ
)を起動するクラス。
遷移元
アクティビティと遷移先
アクティビティの橋渡し役を担う。
Intentクラスのインスタンス化(実体化)
定義
Intent(packageContext: Context!, cls: Class<*>!)
// パラメータ
// packageContext: 遷移元のアクティビティオブジェクト(=コンテキスト)
// cls: Javaクラス化した遷移先アクティビティ
// -> KotlinのクラスをJavaに変換する場合は、"<Kotlinクラス名>::class.java"と記述
Intentオブジェクトへのデータの格納
インテント
を通じてデータをやり取りする場合、Extraデータ
(=追加情報)をIntent
オブジェクトに追加する。
定義
putExtra(name: String!, value: String?): Intent
// パラメータ
// name: 格納するデータの名称
// value: 格納するデータ
遷移先アクティビティの起動(画面遷移)
定義
Activity.startActivity(intent: Intent!): Unit
// パラメータ
// intent: 画面遷移を実現するIntentオブジェクト
サンプルコード
class MainActivity: AppCompatActivity() {
...
// リスナクラス
private inner class ListItemClickListener: AdapterView.OnItemClickListener {
// "タップ"イベント検知時の処理(イベントハンドラ)
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
// "タップ"されたItemの定義
// parent: AdapterView
// getItemAtPosition(): 指定したIndex(position)のtext値を取得(返り値はAny型)
val item = parent?.getItemAtPosition(position) as MutableMap<String, String>
// 指定したキーの値
val menuName = item["name"]
val menuPrice = item["price"]
// 画面遷移を実現するIntentオブジェクトの生成
// Intent(packageContext:cls:): Intentオブジェクトの生成
// packageContext: 遷移元のアクティビティオブジェクト(=コンテキスト)
// cls: Javaクラス化した遷移先アクティビティ
val intent2MenuThanks = Intent(
this@MainActivity,
MenuThanksActivity::class.java
)
// Intentオブジェクトへのデータの格納
// putExtra(name:value:): Intentオブジェクトにデータを格納
// name: 格納するデータの名称
// value: 格納するデータ
intent2MenuThanks.putExtra("menuName", menuName)
intent2MenuThanks.putExtra("menuPrice", menuPrice)
// 遷移先アクティビティの起動
// Context.startActivity(intent:): Intentオブジェクトによる画面遷移の実行
// intent: Intentオブジェクト
startActivity(intent2MenuThanks)
}
}
}
apply関数を用いたIntentオブジェクトの生成・定義
// 発展: apply関数の使用
// 本来はこっち
// 画面遷移を実現するIntentオブジェクトの生成
val intent2MenuThanks = Intent(
this@MainActivity,
MenuTahnksActivity::class.java
)
// Intentオブジェクトへのデータの格納
intent2MenuThanks.putExtra("menuName", menuName)
intent2MenuThanks.putExtra("menuPrice", menuPrice)
// apply関数(スコープ関数)を用いる場合
// -> applyブロック{...}内では、インスタンス変数(intent2MenuThanks)の記述が不要
val intent2MenuThanks = Intent(
this@MainActivity,
MenuTahnksActivity::class.java
).apply {
putExtra("menuName", menuName)
putExtra("menuPrice", menuPrice)
}
遷移先アクティビティの終了
定義
finish(): Unit
遷移先による遷移元の値取得
遷移元
のデータはIntent
オブジェクトが保持しているため、遷移先アクティビティ
でintent
プロパティを用いてデータを取得する。
文字列(String)
定義
Intent.getStringExtra(name: String!): String?
// パラメータ
// name: Intentオブジェクト(=intentプロパティ)に格納されたデータの名称
数値(Int)
定義
Intent.getIntExtra(name: String!, defaultValue: Int): Int
// パラメータ
// name: Intentオブジェクト(=Activity.intent)に格納されたデータの名称
// defaultValue: 取得するデータの初期値
// <- 指定したnameのデータが存在しない場合のnullを避ける
サンプルコード
class MenuThanksActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
...
// Intentオブジェクトが保持するデータの取得
val menuName = intent.getStringExtra("menuName")
val menuPrice = intent.getStringExtra("menuPrice")
// 値を反映する遷移先ビューの定義
val tvMenuName = findViewById<TextView>(R.id.tvMenuName)
val tvMenuPrice = findViewById<TextView>(R.id.tvMenuPrice)
// 遷移先ビューの値(=TextView.text)の変更
tvMenuName.text = menuName
tvMenuPrice.text = menuPrice
}
}
レイアウトファイルによるリスナ定義
参考: タップイベントのイベント処理
イベント
を検知するリスナ
を定義する方法は以下の2つ。
Activity
ファイルでリスナクラス
を定義レイアウトファイル
にandroid:onClick
属性を追加し、その属性値
と一致するイベントハンドラ
をActivity
ファイルに記述
※フラグメント
では実装不可
サンプルコード
<Button
...
android:onClick="onBackButtonClick" <!-- リスナ定義 -->
/>
class MenuThanksActivity: AppCompatActivity() {
...
// "タップ"イベント検知時の処理(イベントハンドラ)
// ※実装にあたって制約が存在(後述)
fun onBackButtonClick(view: View) {
...
}
}
制約
レイアウトファイル
でリスナ
の定義を行う場合、イベントハンドラ
は以下の要件を満たす必要がある。
public
メソッドであること(Kotlin
ではpublic
が規定値)返り値
がない(=Unit型である)ことView
型1つのみの引数
をとること