web-dev-qa-db-ja.com

AndroidデータバインディングはカスタムビューにViewModelを挿入します

私はこのstackoverflowの答えを外します https://stackoverflow.com/a/34817565/4052264 データオブジェクトをカスタムビューに結び付けます。ただし、すべてが設定された後、ビューはデータで更新されず、代わりにTextViewは空白のままになります。これが私のコードです(ここに収まるように簡略化されています):

_activity_profile.xml_:

_<layout xmlns...>
    <data>
        <variable name="viewModel" type="com.example.ProfileViewModel"/>
    </data>
    <com.example.MyProfileCustomView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        app:viewModel="@{viewModel}">
</layout>
_


_view_profile.xml_:

_<layout xmlns...>
    <data>
        <variable name="viewModel" type="com.example.ProfileViewModel"/>
    </data>
    <TextView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:text="@{viewModel.name}">
</layout>
_


_MyProfileCustomView.kt_:

_class MyProfileCustomView : FrameLayout {
    constructor...

    private val binding: ViewProfileBinding = ViewProfileBinding.inflate(LayoutInflater.from(context), this, true)

    fun setViewModel(profileViewModel: ProfileViewModel) {
        binding.viewModel = profileViewModel
    }
}
_



_ProfileViewModel.kt_:

_class ProfileViewModel(application: Application) : BaseViewModel(application) {
    val name = MutableLiveData<String>()

    init {
        profileManager.profile()
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(::onProfileSuccess, Timber::d)
    }

    fun onProfileSuccess(profile: Profile) {
        name.postValue(profile.name)
    }
}
_

すべてが正常に機能し、profileManager.profile()へのAPI呼び出しが成功し、ViewProfileBindingクラスが適切な設定で正常に作成されます。問題は、name.postValue(profile.name)を実行すると、ビューが_profile.name_の値で更新されないことです。

7
Gregriggins36

不足している部分は、 ライフサイクル所有者 を設定することです。

binding.setLifecycleOwner(parent) //parent should be a fragment or an activity
5
rafaelfukuda

答えは私を助け、LifeCycleOwnerを取得するために追加できるutilメソッドをスローしたいと思います

fun getLifeCycleOwner(view: View): LifecycleOwner? {
    var context = view.context

    while (context is ContextWrapper) {
        if (context is LifecycleOwner) {
            return context
        }
        context = context.baseContext
    }

    return null
}

あなたの見解では:

getLifeCycleOwner(this)?.let{
   binding.setLifecycleOwner(it)
}
1
Juan Mendez