既存のJavaで書かれたAndroidアプリをKotlinへ移行中に
気づいたことをまとめていきます。随時追記します。
Code変換
AndroidStudioのメニュー、Code → Convert Java File to Kotlin File
で、Javaファイルがktファイルに変換されます。
↓のメッセージが表示されるかも。
some code in the rest of your project may
require corrections after performing this conversion.
do you want to find such code and correct it too ?
プロジェクトの残りの一部のコードでは、
この変換を実行した後に修正が必要な場合があります。
あなたはそのようなコードを見つけてそれを修正したいでしょうか?
Yes!!
CustomView
例としてスクロールしないListViewなCustomViewを。
@JvmOverloads とか使うこと。
コンストラクタ沢山書かなくていいからいいですね。
class NonScrollListView : ListView {
constructor(context: Context) : super(context) {}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {}
public override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val heightMeasureSpec_custom = View.MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE shr 2, View.MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom)
val params = layoutParams
params.height = measuredHeight
}
}
class NonScrollListView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ListView(context, attrs, defStyleAttr) {
// イニシャライザ(インスタンス生成時の初期処理はここで)
init {
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val heightMeasureSpec_custom = View.MeasureSpec.makeMeasureSpec(
Integer.MAX_VALUE shr 2, View.MeasureSpec.AT_MOST)
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val params = layoutParams
params.height = measuredHeight
}
}
null許容
non-null型なのにnullが入るとこの例外です。
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull
メッセージに続けて変数名とかヒントがあると思うので
?を付けてnull型に
Data Binding
Kotlin用のData Bindingの準備としてGradleに追記します。
追記したあとはCleanだったりAndroidStudioの再起動が必要かも。
レイアウトファイル側はJava時代から変更はありません。そのままでOK
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.1.60'
ext.android_plugin_version = '2.3.3'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
...
dependencies {
...
// Kotlin
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
kapt "com.android.databinding:compiler:$android_plugin_version"
}
Retrofit用データクラス
Listがネストするような場合、Collectionにしたらうまくいった。
class Data {
public List<List<Hoge>> hoge = new ArrayList<>();
}
class Data {
var hoge: Collection<Collection<Hoge>> = ArrayList()
}
LinkedHashMapのキーから値を取得
文字列をキーに数値を持つLinkedHashMapがあったとして
↓のようにキーから値を取得していたコードは
mapHoge["hoge"]
そのままだと↓でエラーなので、値が取得できないケースもデフォルト値でフォローする
Type mismatch.
Required: Int
Found: Int?
mapHoge.getOrDefault("hoge", 123)
継承
// openを付けないと継承できない
open class Base {
}
class Hoge : Base() {
}