【问题标题】:LiveData is not observing on child viewpager fragments having a shared viewmodelLiveData 没有观察具有共享视图模型的子视图页面片段
【发布时间】:2021-10-10 04:26:46
【问题描述】:

LiveData 不会观察子 viewpager 片段,其中子片段具有一个共享视图模型来访问数据。

这里 FragmentA 和 FragmentB 是 viewpager 的一部分,它们都共享一个 viemodel SharedViewModel。

public class SharedViewModel extends AndroidViewModel { //in Java

    private final MutableLiveData<Data> mLiveData = new MutableLiveData<>();
    public LiveData<Data> getLiveData() {
        return mLiveData;
    }

    //for updating data through LiveData, using post as and when I get the response from DataSource as shown below.

    mLiveData.postValue(response); //getting the response on debugging
}
class FragmentA : Fragment()  { //in Kotlin

    override fun onCreate(@Nullable savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
    }

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

        mViewModel.liveData.observe(viewLifecycleOwner, {
            //no call coming in this block so unable to update view
        })
    }
}
class FragmentB : Fragment()  { //in Kotlin

    override fun onCreate(@Nullable savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
    }
}

需要一些帮助来了解为什么实时数据无法观察到变化。

提前致谢。

【问题讨论】:

    标签: android android-fragments android-viewpager android-livedata


    【解决方案1】:

    您的 ViewModel 未共享。您已将其命名为 sharedViewmodel,但您通过传递 Unique Owner 获取它的实例的方式也将是一个 unique instance

    共享视图模型的正确方式是

    class SharedViewModel : ViewModel() {
        private val myLiveData = MutableLiveData<Data>()
    
        fun getMyLiveDta():LiveData {
          return myLiveData
        }
    }
    

    现在在第一个片段中

    class MasterFragment : Fragment() {
    
        private lateinit var itemSelector: Selector
    
        // Get instance of viewmodel in fragment like this
        private val model: SharedViewModel by activityViewModels()
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            
        }
    }
    

    在这样的第二个片段中

    class DetailFragment : Fragment() {
    
        private val model: SharedViewModel by activityViewModels()
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
                // Update the UI
            })
        }
    }
    

    【讨论】:

    • 谢谢MRamzan。使用 ViewModel 初始化的活动范围有助于解决该问题。子片段是 viewpager 的一部分,它本身就是父片段的一部分。我可以有父片段范围而不是活动范围吗?
    • 在您的父片段中,如果您使用 Activity 范围,您可能会遇到内存泄漏,因为在父 Activity 处于活动状态之前,您的 ViewModel 也将可用。
    • 在观察嵌套片段中的数据时,使用 activity 或 getactivity() 代替 viewLifecycleOwner。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多