はじめに
Android等でKotlinを使用している場合、Javaから『Convert Java File to Kotlin File』で自動変換している人は多い。実際にそれでも動くのだが、そこをもう1歩先に進みKotlinをより使いこなす為のメモ。
第2回目
今回はAndroidのActivityのViewの動的処理を習得する。
Kotlinバージョン:1.3
Kotlin変換前のサンプルコード
最初にJavaで書かれたサンプルを用意する。処理は。
public class MainActivity extends AppCompatActivity {
Button buttonA;
TextView textViewA;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonA = (Button) findViewById(R.id.button_A);
buttonA.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("", "buttonA");
}
});
textViewA = (TextView) findViewById(R.id.text_viewA);
textViewA.setText(R.string.text1);
TextView textViewB = (TextView) findViewById(R.id.text_viewB);
textViewB.setText(R.string.text2);
}
@Override
protected void onRestart() {
super.onRestart();
buttonA.setClickable(false);
textViewA.setText(R.string.text2);
}
#Kotlin変換後のサンプルコード
これを自動変換して元の形に合わせるときっとこんな感じに・・・。
class MainActivity : AppCompatActivity() {
var buttonA: Button? = null
var textViewA: TextView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
buttonA = findViewById<View>(R.id.button_A) as Button
buttonA?.setOnClickListener { Log.d("", "buttonA") }
textViewA = findViewById<View>(R.id.text_viewA) as TextView
textViewA?.setText(R.string.text1)
val textViewB = findViewById<View>(R.id.text_viewB) as TextView
textViewB.setText(R.string.text2)
}
override fun onRestart() {
super.onRestart()
buttonA?.isClickable = false
textViewA?.setText(R.string.text2)
}
}
#何が問題か
一応、問題なく動作できるが・・・。
まず、メンバー変数を使用するのに毎回Nullableのアンラップ(buttonA?.・・・)しないといけない。
findViewByIdのas *****
という記述もあまり意味がない。
#実装方法を考える
方法が2つある
1.メンバー変数に「lateinit」を使い、findViewByIdの型を決める
class MainActivity : AppCompatActivity() {
lateinit var buttonA: Button
lateinit var textViewA: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
buttonA = findViewById<Button>(R.id.button_A)
buttonA.setOnClickListener { Log.d("", "buttonA") }
textViewA = findViewById<TextView>(R.id.text_viewA)
textViewA.setText(R.string.text1)
val textViewB = findViewById<TextView>(R.id.text_viewB)
textViewB.setText(R.string.text2)
}
override fun onRestart() {
super.onRestart()
buttonA.isClickable = false
textViewA.setText(R.string.text2)
}
}
2.「Kotlin Android Extensions」を使用する
1の方法でも大丈夫だがもっとシンプルに実装もできる。
それが「Kotlin Android Extensions(公式リンク)」
使用するにはgradleにclasspathの追記が必要
buildscript {
ext.kotlin_version = '1.3.41'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// 以下の行を追加
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
}
}
これで準備OK
findViewByIdを使わなくても実装できるようになる
// ※↓のimportの追記が必要
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button_A.setOnClickListener { Log.d("", "buttonA") }
text_viewA.text = getText(R.string.text1)
text_viewB.text = getText(R.string.text2)
}
override fun onRestart() {
super.onRestart()
button_A.isClickable = false
text_viewA.text = getText(R.string.text2)
}
}
とてもシンプル!