Kotlin实现Android自定义下拉列表控件:完整教程与代码示例
在这个教程中,我们将使用Kotlin讨论和实现Android应用中的Spinner(下拉列表)。Android Spinner用于在屏幕上创建下拉列表。
你将学习什么?
- 通过XML和编程方式创建Spinner
- 在Spinner上设置提示
- 为Spinner创建自定义布局
- 处理点击监听器并显示Toast消息
- 防止点击监听器第一次自动触发
Android Spinner是什么?
Spinner类似于包含一个选择项目列表的下拉菜单。选择一个值后,Spinner将返回到其默认状态,并显示所选的值。在Android 3.0之后,无法在Spinner的默认状态中显示提示信息,而是显示第一个项目。Spinner中的数据由适配器加载。想象一下以下情景:假设您需要给手机充电。为此,您必须使用适配器将手机充电器连接到电力插座。然后适配器提供电力给您的手机。在Android中,Spinner就像您的手机,使用适配器加载数据。适配器设置数据以及要加载到Spinner中的项目的布局。
Spinner回调事件
AdapterView.OnItemSelectedListener接口用于触发Spinner点击事件的回调。它包含两个方法:
- onItemSelected(项目选中)
- onNothingSelected(未选中任何项目)
在接下来的部分中,我们将创建一个新的Android Studio项目,并在我们的应用程序中实现Spinner。我们将自定义布局,并学习如何处理不同的情景。
Android下拉菜单的Kotlin项目

1. XML布局代码
以下是activity_main.xml布局文件的代码。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/linearLayout"
android:gravity="center"
tools:context=".MainActivity">
<Spinner
android:id="@+id/mySpinner"
android:layout_width="match_parent"
android:spinnerMode="dialog"
android:layout_height="wrap_content" />
</LinearLayout>
目前它只能承载一个Spinner,其中android:spinnerMode可以选择dialog(对话框)或dropdown(下拉)两种模式之一。
要显示提示,您应该将spinnerMode的值设置为dialog。
2. Spinner XML 代码
下面给出了spinner_right_aligned.xml的代码。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:padding="15dp"
android:textAlignment="gravity"
android:textColor="@color/colorPrimary"
android:textSize="16sp"
/>
3. 主活动的Kotlin代码
以下是MainActivity.kt类的代码。
package net.androidly.androidspinnerkotlin
import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.widget.*
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(), AdapterView.OnItemSelectedListener {
var languages = arrayOf("Java", "PHP", "Kotlin", "Javascript", "Python", "Swift")
val NEW_SPINNER_ID = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var aa = ArrayAdapter(this, android.R.layout.simple_spinner_item, languages)
aa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
with(mySpinner)
{
adapter = aa
setSelection(0, false)
onItemSelectedListener = this@MainActivity
prompt = "选择你喜欢的编程语言"
gravity = Gravity.CENTER
}
val spinner = Spinner(this)
spinner.id = NEW_SPINNER_ID
val ll = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
ll.setMargins(10, 40, 10, 10)
linearLayout.addView(spinner)
aa = ArrayAdapter(this, R.layout.spinner_right_aligned, languages)
aa.setDropDownViewResource(R.layout.spinner_right_aligned)
with(spinner)
{
adapter = aa
setSelection(0, false)
onItemSelectedListener = this@MainActivity
layoutParams = ll
prompt = "选择你喜欢的编程语言"
setPopupBackgroundResource(R.color.material_grey_600)
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
showToast(message = "未选择任何项目")
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when (view?.id) {
1 -> showToast(message = "Spinner 2 位置:${position},语言:${languages[position]}")
else -> {
showToast(message = "Spinner 1 位置:${position},语言:${languages[position]}")
}
}
}
private fun showToast(context: Context = applicationContext, message: String, duration: Int = Toast.LENGTH_LONG) {
Toast.makeText(context, message, duration).show()
}
}
重要观点:
- 感谢Kotlin Android扩展,XML Spinner控件在我们的Kotlin Activity类中自动可用。
- 我们创建了一个包含编程语言的字符串数组。这些数据通过ArrayAdapter填充到适配器中。
- setDropDownViewResource用于设置选中状态和Spinner列表行的布局。
- android.R.layout.simple_spinner_item用于设置默认的Android SDK布局。默认情况下,TextView在此类型布局中是左对齐的。
我们通过编程方式创建了第二个Spinner,该Spinner从spinner_right_aligned.xml文件中加载布局。
当Activity被创建时,使用setSelection(0, false)可以防止Spinner的OnItemSelected方法触发。
这是如何工作的?setSelection()方法告诉Activity第一个下拉菜单项已经被选择。我们必须将这个语句放在onItemSelectedListener = this之前。setPopupBackgroundResource用于设置下拉列表的背景颜色。在onItemSelected函数中,我们使用when语句触发相应Spinner项的Toast消息。多亏了Kotlin和带有默认值的函数,我们减少了对Toast的冗长调用。
4. Kotlin应用程序的输出结果
