Activity間で自作ArrayListを渡す方法

Activity間で自作ArrayListを渡す方法です。
Kotlinです。
Parcelable化するところが肝です。

流れ

一覧画面から詳細画面に自作クラスのArrayListを渡す流れです。

一覧画面
MyListActivity.kt
詳細画面
MyDetailActivity.kt
渡すデータ
MyDataList:ArrayList<MyData>

送信元のActivity(MyListActivity.kt

1
2
3
4
val intent = Intent(this, MyDetailActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putParcelableArrayListExtra("MyDataList", MyDataList.list);
startActivity(intent)

送信するデータのリスト(MyDataList.kt

1
2
3
4
5
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class MyDataList(var list:ArrayList<MyData>) : Parcelable

送信する個別データ(MyData.kt

1
2
3
4
5
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class MyData(var timeStamp: String) : Parcelable

送信先のActivity(MyDetailActivity.kt

1
2
3
4
5
6
7
8
9
10
11
12
13
import android.os.Bundle

class MyDetailActivity : Activity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 本来はgetParcelableExtraが正しそうだけど以下のエラーになるのでgetSerializableExtraを使う
// Not enough information to infer type variable T
// val myDataList = intent.getParcelableExtra("MyDataList") as ArrayList<MyData>
val myDataList = intent.getSerializableExtra("MyDataList") as ArrayList<*>
setContentView(view)
}
}

ちなみにMyDataがただのStringやIntgerならputStringArrayListExtraなどを使えば良いのでParcelable化する必要はないです。

今回はMyDataが自作クラスなのでputParcelableArrayListExtraを使う必要があり、これを使うためにParcelable化が必要だったということです。

以上です。

Kotlinの勉強メモ

日本語化
https://sukkiri.jp/technologies/ides/intellij-idea/intellij-idea-mac.html

Kotlin Bootcamp for Programmers 2
https://codelabs.developers.google.com/codelabs/kotlin-bootcamp-basics/#0

  • 変数を宣言する時に自動的に型が設定される(明示的に型を宣言することも可能)
  • 変数に別の方の値を代入するとエラーになる(自動的に型変換されない)
  • val→ 値を変更不可能
  • var→ 値を変更可能
  • 変数の結合は+演算子
  • 通常は変数に null を入れることはできない
  • 入れたい場合はvar marbles: Int? = nullのように?を付けて宣言する
  • null だったらエラーを吐く場合は!!を使う →val len = s!!.length
  • リストの宣言は listOf→val school = listOf("mackerel", "trout", "halibut")
  • 配列の宣言は listOf→val school = arrayOf("shark", "salmon", "minnow")
  • リストは要素数が可変だけど配列の方がアクセスが早い

配列を for ループ

1
2
3
4
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
print(element + " ")
}

配列をインデックス付きの for ループ

1
2
3
for ((index, element) in school.withIndex()) {
println("Item at $index is $element\n")
}
  • main()に引数を渡す →[実行]> [構成の編集]>[プログラム引数]

関数を1行で書く

1
fun isTooHot(temperature: Int) = temperature > 30

リストから一部だけ抽出

1
2
3
4
5
6
val decorations = listOf("rock", "pagoda", "plastic plant", "alligator", "flowerpot")
// 先頭がpの文字列だけを抽出
val eager = decorations.filter({x -> x[0] == 'p'})
// 以下は等価
// val eager = decorations.filter {it[0] == 'p'}
println("eager: $eager")

ラムダ関数

  • ラムダ関数(無名関数)を waterFilter 変数に入れている
  • 引数として Int 型を受け取り、Int 型を返す
1
2
3
4
5
6
val waterFilter: (Int) -> Int = { dirty -> dirty / 2 }

// 引数が1つの場合はitとして表現可能
val waterFilter: (Int) -> Int = { it / 2 }

waterFilter(10)

関数を引数に与える時は::を使う

1
2
fun increaseDirty( start: Int ) = start + 1
println(updateDirty(15, ::increaseDirty))
1
2
fun increaseDirty( start: Int ) = start + 1
println(updateDirty(15, ::increaseDirty))

クラスの変数に設定できる修飾子は以下の4つ
アクセス可能な範囲は以下の通り

  1. public→ どこからでも
  2. internal→ 同じモジュール内であれば
  3. private→ 同じクラス内であれば
  4. protected→ 同じサブクラス内であれば

クラスやクラス内変数はデフォルトだとサブクラスによる上書きはできない
上書きを許可する場合はopenをつける →open val shape = "rectangle"

Aquarium クラスを TowerTank がオーバーライドする例

1
2
3
4
5
6
7
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
override var volume: Int
// ellipse area = π * r1 * r2
get() = (width/2 * length/2 * height / 1000 * PI).toInt()
set(value) {
height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
}
  • ラムダ式のreturnは外側の関数のreturnとなる
  • 関数の早期脱出が目的であればラムダ式ではなく代わりに匿名関数を利用する必要がある
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×