在這篇文章中,有些地方通用於其他元件。這篇就以 button 的點擊監聽器作為示範,讓大家在其中慢慢體會到 kotlin 的寫法。
在前面的文章有提到,kotlin 的 getter and setter 用法跟 java 不同,看起來很像是可以直接做使用。有 getter and setter 的屬性大多都是這麼做的,像長寬、顏色、文字等等。文字使用的常用單位是 sp
textView.text= "Jack"
val name= textView.text
在這裡常用的單位是 dp,除了直接設定多少點以外,還可以是設以下
或者是有要填滿元件之間的空間,可以用 constrain layout 配上 0dp
例如 tab layout 底下的 fragment
<fragment
android:id="@+id/frgFragment"
android:name="com.example.simplewidgetshowcase.MyFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tablayoutFragment" />
在 kotlin 中使用元件的時候跟 java 一樣,要先透過 findViewById()
。以下就在 activity 的 onCreate()
方法中做示範
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val text: TextView= findViewById(R.id.textMain)
val btn: Button= findViewById(R.id.btnMain)
}
}
但是,並不是只有 onCreate()
中會用到元件,比如說 class 裡的其他 function 也有可能會,此時就不能只宣告在 onCreate()
裡面。
Java 裡的作法,是在 class 做成員宣告然後 onCreate()
做初始化。Kotlin 也是一樣的方法
class MainActivity : AppCompatActivity() {
private var text: TextView
private var btn: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text: TextView= findViewById(R.id.textMain)
btn: Button= findViewById(R.id.btnMain)
}
}
很快的就會發現出錯了。
還記得前幾篇說的 kotlin 要初始化嗎?因為我們很確定在 onCreate()
裡面會初始化,所以就大膽的把 lateinit 加上去!
class MainActivity : AppCompatActivity() {
private lateinit var text: TextView
private lateinit var btn: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text: TextView= findViewById(R.id.textMain)
btn: Button= findViewById(R.id.btnMain)
}
}
一個按鈕最重要的功能就是點擊了,這裡提供三個可以建立點擊監聽器的方法。
在 XML 檔中,對你要的 Button 新增屬性 android:onClick:=""
打入你要的 function 名稱後
<Button
android:id="@+id/btnMain"
android:text="Button"
android:onClick="btnMainClick"
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
會出現錯誤,因為我們還沒有新增該名稱的方法
按下 ctrl + enter 迅速建立方法
回 kt 檔就可以看到 function 建立完成了
fun btnMainClick(view: View) {}
往後當按鈕被點下的時候,就會呼叫此方法。
這個方法是透過 activity implement View.OnClickListener
Kotlin 的繼承 class 會加上括號,實作 interface 則不用加
還要記得要實現它的方法
class MainActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var text: TextView
private lateinit var btn1: Button
private lateinit var btn2: Button
private lateinit var btn3: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text: TextView= findViewById(R.id.textMain)
btn1: Button= findViewById(R.id.btnMain1)
btn2: Button= findViewById(R.id.btnMain2)
btn3: Button= findViewById(R.id.btnMain3)
btn1.setOnClickListener(this)
btn2.setOnClickListener(this)
btn3.setOnClickListener(this)
}
}
記得要設定 OnClickListener 在 this
override fun onClick(p0: View?) {
when(p0?.id){
R.id.btnMain1 -> {
text.text= "Button1 is Clicked!"
}
R.id.btnMain2 -> {
text.text= "Button2 is Clicked!"
}
R.id.btnMain3 -> {
text.text= "Button3 is Clicked!"
}
}
}
when 就等同於 java 的 switch,透過 when 判斷式得知是哪一個按鈕被點擊。如果只有一行的話
這個是我現在這在使用的,相比於前幾個更簡潔。其實在前一篇的 Lambda 就介紹過了
class MainActivity : AppCompatActivity() {
private lateinit var text: TextView
private lateinit var btn: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
text: TextView= findViewById(R.id.textMain)
btn: Button= findViewById(R.id.btnMain)
btn1.setOnClickListener{
text.text= "Button is Clicked!"
}
}
}