任何人都可以指导我有关如何使用与AppCompatAutoCompleteTextView进行数据绑定来设置适配器并获得价值
答案 0 :(得分:1)
最后,我得到了像这样的解决方案image
BindingAdapter.kt
@JvmStatic
@BindingAdapter("valueAttrChanged")
fun MyAutoCompleteSpinner.setListener(listener: InverseBindingListener?) {
this.onItemSelectedListener = if (listener != null) {
object : AdapterView.OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
listener.onChange()
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
listener.onChange()
}
}
} else {
null
}
}
@JvmStatic
@get:InverseBindingAdapter(attribute = "value")
@set:BindingAdapter("value")
var MyAutoCompleteSpinner.selectedValue: String?
get() {
return if (listSelection != ListView.INVALID_POSITION) {
adapter.getItem(listSelection).toString()
} else {
null
}
}
set(value) {
val newValue = value ?: adapter.getItem(0).toString()
setText(newValue, true)
if (adapter is ArrayAdapter<*>) {
val position = (adapter as ArrayAdapter<String?>).getPosition(newValue)
listSelection = position
}
}
@JvmStatic
@BindingAdapter("entries", "itemLayout", "textViewId", requireAll = false)
fun MyAutoCompleteSpinner.bindAdapter(entries: Array<String>, @LayoutRes itemLayout: Int?, @IdRes textViewId: Int?) {
val adapter = when {
itemLayout == null -> {
ArrayAdapter(context, android.R.layout.simple_list_item_1, android.R.id.text1, entries)
}
textViewId == null -> {
ArrayAdapter(context, itemLayout, entries)
}
else -> {
ArrayAdapter(context, itemLayout, textViewId, entries)
}
}
setAdapter(adapter)
}
layout.xml
....
<data>
<variable
name="viewmodel"
type="com.example.vm.ViewModel" />
</data>
.......
.......
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Gender">
<com.example.widget.MyAutoCompleteSpinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
entries="@{@stringArray/genders}"
value="@{viewmodel.gender}"/>
</com.google.android.material.textfield.TextInputLayout>
....
MyAutoCompleteSpinner.kt
package com.example.widget
import android.content.Context
import android.graphics.Color
import android.graphics.Rect
import android.util.AttributeSet
import android.view.MotionEvent
import com.google.android.material.textview.MaterialAutoCompleteTextView
import timber.log.Timber
class MyAutoCompleteSpinner : MaterialAutoCompleteTextView {
constructor(context: Context) : this(context, null)
constructor(arg0: Context, arg1: AttributeSet?) : super(arg0, arg1)
constructor(arg0: Context, arg1: AttributeSet, arg2: Int) : super(arg0, arg1, arg2)
init {
isCursorVisible = false
setEnableSpinner(false)
setTextColor(Color.BLACK)
}
override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
super.onFocusChanged(focused, direction, previouslyFocusedRect)
if (focused && filter != null) {
performFiltering(null, 0)
}
setEnableSpinner(false)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
Timber.d(event?.action.toString())
when {
event?.action == MotionEvent.ACTION_MOVE -> {
setEnableSpinner(true)
}
event?.action == MotionEvent.ACTION_UP -> {
setEnableSpinner(true)
}
event?.action == MotionEvent.ACTION_DOWN -> {
setEnableSpinner(true)
}
}
if(event?.action == MotionEvent.ACTION_UP) {
if(event.rawX <= totalPaddingLeft) {
setEnableSpinner(true)
return true
}
}
return super.onTouchEvent(event)
}
fun setEnableSpinner(enable: Boolean){
this.isEnabled = enable
}
override fun performFiltering(text: CharSequence?, keyCode: Int) {
super.performFiltering(null, keyCode)
}
}
string.xml
<string-array name="genders">
<item>"Male"</item>
<item>"Female"</item>
</string-array>