Android中的AutoCompleteTextView或Spinner数据绑定

时间:2019-11-06 19:48:50

标签: android-studio android-layout data-binding android-databinding autocompletetextview

任何人都可以指导我有关如何使用与AppCompatAutoCompleteTextView进行数据绑定来设置适配器并获得价值

1 个答案:

答案 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>