Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
android在两个片段之间实现ViewModel,而不使用getActivity()_Android_Android Fragments_Android Viewmodel - Fatal编程技术网

android在两个片段之间实现ViewModel,而不使用getActivity()

android在两个片段之间实现ViewModel,而不使用getActivity(),android,android-fragments,android-viewmodel,Android,Android Fragments,Android Viewmodel,我的应用程序中有2个片段。当用户单击第一个片段中的按钮时,会添加第二个片段,以便用户可以插入一些数据。然后它关闭并将插入的数据返回给第一个片段。我已经使用ViewModels来实现片段之间的通信 collectionsEditedViewModel = new ViewModelProvider(getActivity()).get(CollectionsEditedViewModel.class); collectionsEditedViewModel.isEdited().o

我的应用程序中有2个片段。当用户单击第一个片段中的按钮时,会添加第二个片段,以便用户可以插入一些数据。然后它关闭并将插入的数据返回给第一个片段。我已经使用ViewModels来实现片段之间的通信

    collectionsEditedViewModel = new ViewModelProvider(getActivity()).get(CollectionsEditedViewModel.class);
    collectionsEditedViewModel.isEdited().observe(getViewLifecycleOwner(), new Observer<Bundle>() {
        @Override
        public void onChanged(Bundle bundle) {
        }
    });
collectionsEditedViewModel=新的ViewModelProvider(getActivity()).get(collectionsEditedViewModel.class);
collectionsEditedViewModel.isEdited().observe(getViewLifecycleOwner(),new Observer()){
@凌驾
更改后的公共无效(捆绑){
}
});

通讯正常。但问题是我如何在片段中定义这种通信的范围。目前,我正在使用
getActivity()
作为
ViewmodelStoreOwner
,这会使集合数据在重新打开时重新传递到第一个片段。我如何解决这个问题?

我认为,对于片段之间的通信,通过活动是一种方式,因此您走的是正确的道路

您可以做的一件事是使用SingleLiveData类,该类本质上类似于LiveData,但在设置其值后,它将被置为null,因此只有第一个观察者才能获得它:

class SingleLiveData<T> : MutableLiveData<T>() {

    private val mPending = AtomicBoolean(false)

    @MainThread
    override fun observe(owner: LifecycleOwner, observer: Observer<T>) {

        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
        }

        // Observe the internal MutableLiveData
        super.observe(owner, Observer { t ->
            if (mPending.compareAndSet(true, false)) {
                observer.onChanged(t)
            }
        })
    }

    @MainThread
    override fun setValue(t: T?) {
        mPending.set(true)
        super.setValue(t)
    }

    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    fun call() {
        value = null
    }

    companion object {
        private val TAG = "SingleLiveData"
    }
}
class SingleLiveData:MutableLiveData(){
private val mPending=AtomicBoolean(false)
@主线
覆盖乐趣观察(所有者:生命周期所有者,观察者:观察者){
if(hasActiveObservers()){
w(标签,“注册了多个观察者,但只有一个会收到更改通知。”)
}
//观察内部的可变LiveData
超级观察者(所有者、观察者{t->
if(mPending.compareAndSet(真、假)){
观察员:一旦改变(t)
}
})
}
@主线
覆盖设置值(t:t?){
mPending.set(真)
超级设定值(t)
}
/**
*用于T为空的情况,使呼叫更干净。
*/
@主线
趣味电话(){
值=空
}
伴星{
private val TAG=“SingleLiveData”
}
}
然后,您可以简单地调用:
singleLiveData.call()
用于“设置并销毁”,因此,在第一次使用后忘记您的值!从以下位置检索的类(并在我的项目中使用了多年):

谢谢。但它是用科特林写成的。我如何在java代码中使用它?!Kotlin的设计考虑到Java的互操作性,因此只要您的项目支持Kotlin(您只需简单地添加必要的插件:),您就可以在Java中定义一个变量,并使用完全相同的调用:singleLiveData.call();这也是一个很好的机会来了解Kotlin的优点,并在其中编写下一节课!