Привязка данных - жилые данные с пользовательским объектом не были запущены - PullRequest
0 голосов
/ 12 июня 2019

У меня возникают некоторые проблемы с привязкой данных и liveata, когда у меня есть пользовательский объект.

Например:

У меня есть MutableLiveData val user = MutableLiveData<User>()

и я использую двустороннюю привязку данных с @={viewModel.user.name}

Но мой наблюдатель не был уволен внутри Фрагмента с viewModel.user.observer.

Когда я помещаю точку останова в сгенерированный класс FragmentBinding, я вижу, что вызывается setValue и пользовательские значения userLiveData с данными.

Проблема в том, что наблюдатель не был уволен из фрагмента.

Кто-нибудь знает, что я там делаю не так?

РЕДАКТИРОВАТЬ 1

Ниже мой фрагмент кода:

val infoPessoalViewModel: InfoPessoalViewModel by viewModel()
lateinit var bindingView: FragmentInfoPessoalBinding

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

    bindingView = DataBindingUtil.inflate(inflater, R.layout.fragment_info_pessoal, container, false)

    return bindingView.root
}

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    bindingView.apply {
        lifecycleOwner = this@InfoPessoalFragment
        viewModel = infoPessoalViewModel
    }

    infoPessoalViewModel.user.observe(this, Observer { user ->
        user.confirmEmail?.let {
            //NOT FIRED HERE
            Log.d("LiveData","Fired!")
        }
    })
}

РЕДАКТИРОВАТЬ 2

Извините, я приводил пример переменных с именами различий.

1 Ответ

0 голосов
/ 12 июня 2019

Ваша логика BindingAdapter должна быть в состоянии преобразовать вход EditText в экземпляр User и наоборот.Допустим, экземпляр User выглядит следующим образом:

User.kt

class User(val username: String)

Тогда пример адаптера должен быть:

MyBindingAdapters.kt

/**
 *  Convert EditText input into a User instance.
 */
@InverseBindingAdapter(attribute = "android:text")
fun getUser(view: EditText): User {
    return User(view.text.toString())
}

/**
 *  Convert a User instance into EditText text
 */
@BindingAdapter("android:text")
fun setUser(view: EditText, newUser: User?) {
    if (newUser?.username != view.text.toString()) {
        view.setText(newUser?.username)
    }
}

В файле макета свяжите с userLiveData

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@={viewModel.userLiveData}"/>


Обратите внимание, что адаптеры являются биективными,то есть один User в паре с ровно одним String и наоборот.Если класс User является более сложным, то двухстороннее связывание с MutableLiveData<User> на самом деле не имеет смысла.В таком случае вам следует вместо этого связать его с MutableLiveData<String> и вручную обновить экземпляр User в модели представления.

...