在 kotlin 中单击按钮时如何将健康水平降低 1?
How to reduce a healthlevel by 1 when a button is clicked in kotlin?
我从科特林开始。我无法理解 OnClickListener。这里将初始健康等级设置为10后,我需要将健康等级降低1并显示出来。到目前为止,我已经初始化了 healthlevel 并设置了 onclick,但是如何声明将其减少 1 的函数并在单击按钮时调用它?
val TAG = "MyMessage"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.i("LIFECYCLE", "OnCreate")
}
private var healthLevel: Int = 10 //Set the initial health level to 10
private lateinit var healthLevelTextView: TextView
private lateinit var sneezeBtn: Button
private lateinit var takeMedicationButton: Button
private lateinit var blowNoseButton: Button
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("Answer", healthLevel)
Log.i(TAG, "Called SaveInstanceState()")
}
sneezeBtn.setOnClickListener{ _ ->
// the function goes here
}
您可以使用以下方式更改 healthLevel
变量:
sneezeBtn.setOnClickListener {
healthLevel--
healthLevelTextView.setText(healthLevel.toString())
}
附带说明一下,如果您使用 lateinit
,您将失去 Kotlin 的最佳功能之一,即 Null Safety。如果你还不知道如何使用它,我建议你尽快开始学习它。
您还可以将 Android 的一个非常好的功能与 kotlin 一起使用,其中您的视图的对象会在您的 Activity 中自动生成,您只需键入 XML视图 ID,而不必在任何地方都使用 findViewById
。
我假设,您的代码示例在 Activity class 中并且您有一个布局文件 activity_main.xml
,它看起来像这样:
...
<TextView
android:id="@+id/healthLevelTextViewId"
...
/>
<Button
android:id="@+id/sneezeBtnId"
...
/>
...
这将是具有您所需功能的代码:
class YourActivity : Activity {
private var healthLevel: Int = 10
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// retrieve references to the text view and button
val healthLevelTextView = findViewById<TextView>(R.id.healthLevelTextViewId)
val sneezeBtn = findViewById<Button>(R.id.sneezeBtnId)
// the OnClickListener must be initialized within a method body, as it is not a method itself.
sneezeBtn.setOnClickListener { _ ->
// implementation from the answer from Vitor Ramos
healthLevel--
healthLevelTextView.setText(healthLevel.toString())
}
}
}
您可以进一步改进代码:
- 将
apply plugin: 'kotlin-android-extensions'
添加到您应用的 build.gradle
文件中。然后您可以直接使用它们的 ID 引用您的视图。所以而不是
val sneezeBtn = findViewById<Button>(R.id.sneezeBtnId)
sneezeBtn.setOnClickListener { ... }
您可以像这样直接使用 Id:
sneezeBtnId.setOnClickListener { ... }
AndroidStudio 会提示您为 sneezeBtnId
. 添加导入
- 使用View Models, LiveData and Data Binding。这是推荐的,但有点更高级的技术。
Vitor 有答案,但还有几个备选方案...
您可能想要创建一个函数来更新 和 一起显示您的值:
fun setHealth(health: Int) {
healthLevel = health
healthLevelTextView.text = healthLevel
}
这将更新与显示更改结合在一起,因此这两件事总是同时发生。如果你总是用这个函数设置healthLevel
(而不是直接设置变量),显示和值将始终同步
override fun onCreate(savedInstanceState: Bundle?) {
// set your view variables, so the TextView is ready to update
setHealth(INITIAL_HEALTH_VALUE)
如果你愿意,Kotlin lets us put a setter function on the variable itself
var healthLevel: Int = 10
set(value) {
field = value
healthLevelTextView.text = health
}
因此每次更改 healthLevel
的值时,它也会更新显示。您也可以使用 observable
委托
var healthLevel: Int by Delegates.observable(10) { _, oldValue, newValue ->
healthLevelTextView.text = newValue
}
这些比仅仅设置值和自己更新视图更高级,只是指出它们作为替代方法存在,以及将您的逻辑保持在一个地方的方法。同样对于这些示例,它们仅 运行 您 首次设置值后的代码 - 在这两种情况下它们的默认值为 10,但初始化该默认值不会 运行 setter 代码或可观察函数。所以你仍然需要去 healthLevel = 10
让文本显示初始值。
我从科特林开始。我无法理解 OnClickListener。这里将初始健康等级设置为10后,我需要将健康等级降低1并显示出来。到目前为止,我已经初始化了 healthlevel 并设置了 onclick,但是如何声明将其减少 1 的函数并在单击按钮时调用它?
val TAG = "MyMessage"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.i("LIFECYCLE", "OnCreate")
}
private var healthLevel: Int = 10 //Set the initial health level to 10
private lateinit var healthLevelTextView: TextView
private lateinit var sneezeBtn: Button
private lateinit var takeMedicationButton: Button
private lateinit var blowNoseButton: Button
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putInt("Answer", healthLevel)
Log.i(TAG, "Called SaveInstanceState()")
}
sneezeBtn.setOnClickListener{ _ ->
// the function goes here
}
您可以使用以下方式更改 healthLevel
变量:
sneezeBtn.setOnClickListener {
healthLevel--
healthLevelTextView.setText(healthLevel.toString())
}
附带说明一下,如果您使用 lateinit
,您将失去 Kotlin 的最佳功能之一,即 Null Safety。如果你还不知道如何使用它,我建议你尽快开始学习它。
您还可以将 Android 的一个非常好的功能与 kotlin 一起使用,其中您的视图的对象会在您的 Activity 中自动生成,您只需键入 XML视图 ID,而不必在任何地方都使用 findViewById
。
我假设,您的代码示例在 Activity class 中并且您有一个布局文件 activity_main.xml
,它看起来像这样:
...
<TextView
android:id="@+id/healthLevelTextViewId"
...
/>
<Button
android:id="@+id/sneezeBtnId"
...
/>
...
这将是具有您所需功能的代码:
class YourActivity : Activity {
private var healthLevel: Int = 10
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// retrieve references to the text view and button
val healthLevelTextView = findViewById<TextView>(R.id.healthLevelTextViewId)
val sneezeBtn = findViewById<Button>(R.id.sneezeBtnId)
// the OnClickListener must be initialized within a method body, as it is not a method itself.
sneezeBtn.setOnClickListener { _ ->
// implementation from the answer from Vitor Ramos
healthLevel--
healthLevelTextView.setText(healthLevel.toString())
}
}
}
您可以进一步改进代码:
- 将
apply plugin: 'kotlin-android-extensions'
添加到您应用的build.gradle
文件中。然后您可以直接使用它们的 ID 引用您的视图。所以而不是
您可以像这样直接使用 Id:val sneezeBtn = findViewById<Button>(R.id.sneezeBtnId) sneezeBtn.setOnClickListener { ... }
AndroidStudio 会提示您为sneezeBtnId.setOnClickListener { ... }
sneezeBtnId
. 添加导入
- 使用View Models, LiveData and Data Binding。这是推荐的,但有点更高级的技术。
Vitor 有答案,但还有几个备选方案...
您可能想要创建一个函数来更新 和 一起显示您的值:
fun setHealth(health: Int) {
healthLevel = health
healthLevelTextView.text = healthLevel
}
这将更新与显示更改结合在一起,因此这两件事总是同时发生。如果你总是用这个函数设置healthLevel
(而不是直接设置变量),显示和值将始终同步
override fun onCreate(savedInstanceState: Bundle?) {
// set your view variables, so the TextView is ready to update
setHealth(INITIAL_HEALTH_VALUE)
如果你愿意,Kotlin lets us put a setter function on the variable itself
var healthLevel: Int = 10
set(value) {
field = value
healthLevelTextView.text = health
}
因此每次更改 healthLevel
的值时,它也会更新显示。您也可以使用 observable
委托
var healthLevel: Int by Delegates.observable(10) { _, oldValue, newValue ->
healthLevelTextView.text = newValue
}
这些比仅仅设置值和自己更新视图更高级,只是指出它们作为替代方法存在,以及将您的逻辑保持在一个地方的方法。同样对于这些示例,它们仅 运行 您 首次设置值后的代码 - 在这两种情况下它们的默认值为 10,但初始化该默认值不会 运行 setter 代码或可观察函数。所以你仍然需要去 healthLevel = 10
让文本显示初始值。