Android Two Way Databinding работает только в одну сторону - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть ViewModel:

class MyViewModel : ViewModel(){
    private val _user = MutableLiveData("")

    val user: LiveData<String> = _user

    fun onBtnClick(){
        Log.i("MyViewModel", "user: ${_user.value}")
    }
}

Я связал его с разметкой фрагмента, используя:

<data>
    <variable
        name="viewmodel"
        type="com.pkg.pkg.pkg.fragments.concretePkg.MyViewModel" />
</data>
<EditText
    ...
    android:text="@={viewmodel.user}"
    android:hint="User" />

И в классе фрагмента в методе onCreateView:

binding = DataBindingUtil.inflate(inflater, R.layout.fragment_my_fragment, container, false)
binding.lifecycleOwner = this
// bind viewModel
viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java)
binding.viewmodel = viewModel

// Inflate the layout for this fragment
return binding.root

Я могу изменить значение EditText из фрагмента или класса ViewModel, но когда я пытаюсь получить значение внутри метода onBtnClick метода ViewModel в Logcat, я получаю сообщение: I/MyViewModel: user: Чего мне здесь не хватает, такчто двусторонняя привязка данных работает и с другой стороны? Короче говоря, данные передаются из ViewModel / Fragment в EditText в интерфейсе, но не перетекают из EditText в интерфейсе в поля / методы ViewModel. Заранее спасибо.

------- РЕДАКТИРОВАНИЕ ----- Мне удалось все заполнить, но я знаю, что получаю эту ошибку:

Details: There is no inverse for method getValue, you must add an @InverseMethod annotation to the method to indicate which method should be used when using it in two-way binding expressions

Я полагаю, что этопотому что viewmodel.user имеет тип LiveData, а не строку. Я написал адаптер привязки:

@BindingAdapter("android:text")
    fun setLiveDataText(editText: EditText, liveData: LiveData<String>) {
            if(liveData == null){
                editText.setText("")
            } else {
                editText.setText(liveData.value)
            }
        }

Но я все еще получаю сообщение выше.

Ответы [ 2 ]

0 голосов
/ 30 сентября 2019

Чтобы ответить на этот вопрос, вы должны добавить его в build.gradle:

implementation "android.arch.lifecycle:extensions:1.1.1"

И версия kotlin должна быть понижена:

ext.kotlin_version = '1.3.41'

Приветствия!

0 голосов
/ 30 сентября 2019

Во-первых, вы должны сделать _user публичным. Затем вам нужно использовать "@={viewmodel._user}", чтобы вы могли получить значение _user. API привязки данных не может понять и сгенерировать код, если вы не сделаете вашу переменную привязки данных общедоступной. Для простых полей, таких как Strings, этого подхода будет достаточно, но вам, возможно, придется реализовать BindingAdapters для более сложных ситуаций. См. эту статью для примеров.

...