前言
最近在项目中开始使用 Databinding
,其中有一个需求是实现一个 Spinner
列表。发现网上大部分的例子都是通过 @BindingAdapter
的方式去获取 Item
被选中的值,这样处理起来比较麻烦。下面介绍一种简单的方式,笔者在项目中使用了 LiveData
和 ViewModel
,以下基于此实现。
实现
首先添加 LiveData
和 ViewModel
的依赖:
implementation 'android.arch.lifecycle:extensions:1.1.1'
- 新建
SpinnerViewModel
类,来存储 UI 相关的数据
class SpinnerViewModel : ViewModel() {
// Spinner Adapter 需要的数据源
val items = arrayListOf("苍井空", "波多野结衣", "武藤兰", "泷泽萝拉")
// 条目选中的位置
val itemPosition = MutableLiveData<Int>()
// 选择的条目
private val selectItem
get() = itemPosition.value?.let {
items.get(it)
}
fun choose() {
println("选择的是: $selectItem")
}
}
- 在
xml
中进行绑定
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.i3kmsteady.databindingsample.ui.SpinnerViewModel"/>
</data>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
tools:context=".ui.SpinnerActivity">
<android.support.v7.widget.AppCompatTextView
android:id="@+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/familiar_with"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<android.support.v7.widget.AppCompatSpinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:entries="@{ viewModel.items }"
android:selectedItemPosition="@={ viewModel.itemPosition }" // 双向绑定 @=
app:layout_constraintLeft_toRightOf="@id/tvName"
app:layout_constraintRight_toRightOf="parent"/>
<Button
android:id="@+id/btnChoose"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/your_choose"
android:onClick="@{ () -> viewModel.choose()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</android.support.constraint.ConstraintLayout>
</layout>
- 在
Activity
中建立联系
class SpinnerActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_spinner)
val viewModel = ViewModelProviders
.of(this)
.get(SpinnerViewModel::class.java)
val binding: ActivitySpinnerBinding = DataBindingUtil.setContentView(this, R.layout.activity_spinner)
binding.let {
it.viewModel = viewModel
it.setLifecycleOwner(this)
}
}
}
这样在我们点击按钮的时候,就可以获取到 Item
的值。以上代码托管在 GitHub。
结语
实现特别简单,主要是利用了 Databindig
双向绑定的特性。在此也特别感谢 却把清梅嗅 的指导。