Data binding - XML not updating after onActivityResult

回眸只為那壹抹淺笑 提交于 2021-02-10 13:10:38

问题


Updating ObservableField inside onActivityResult(..) of activity but not reflecting that value to XML. If I call executePendingBindings() it will work. But the issue is, there are a lot of ObservableField and for every variable, I need to call executePendingBindings().

Anyone knows how to solve this issue ?


回答1:


In ViewDataBinding.java file, there is one method for requesting rebind

protected void requestRebind() {
        if (mContainingBinding != null) {
            mContainingBinding.requestRebind();
        } else {
            synchronized (this) {
                if (mPendingRebind) {
                    return;
                }
                mPendingRebind = true;
            }
            if (mLifecycleOwner != null) {
                Lifecycle.State state = mLifecycleOwner.getLifecycle().getCurrentState();
                if (!state.isAtLeast(Lifecycle.State.STARTED)) {
                    return; // wait until lifecycle owner is started
                }
            }
            if (USE_CHOREOGRAPHER) {
                mChoreographer.postFrameCallback(mFrameCallback);
            } else {
                mUIThreadHandler.post(mRebindRunnable);
            }
        }
    }

When control enters that method mPendingRebind will be false and it will be made true by this method. mChoreographer.postFrameCallback(mFrameCallback); will make that variable again to false so that other bindings will update the view.

The issue was !state.isAtLeast(Lifecycle.State.STARTED) condition. Since ObservableField is updated from onActivityResult(..), the current state will be Lifecycle.State.CREATED So that condition will fail and return that method without calling mChoreographer.postFrameCallback(mFrameCallback); and mPendingRebind will be true. So remaining bindings will not update.

So the solution was to call SingleLiveEvent and observe that variable. When that callback is received, we have to update ObservableField()

For eg :

val updateObserver = SingleLiveEvent<Unit>()

Then observe for that event

updateObserver.observe(this, Observer { 
            //update ObservableField
        })

Call that event from onActivityResult

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == 111 && resultCode == Activity.RESULT_OK) {
               updateObserver.call()
            }
    }



回答2:


If you don't want to create a SingleLiveEvent and prefer to keep your callback code in onActivityResult, and you have a base activity where all activities extend from, you can add a scheduleUpdateAfterOnActivityResult method to the base activity:

// When onActivityResult is run, the activity is still in Lifecycle.State.CREATED and
// bindings will not fire.  Schedule the update by creating a new MutableLiveData,
// which will fire observers when activity lifecycle is active.
// See also https://stackoverflow.com/questions/53104670/data-binding-xml-not-updating-after-onactivityresult/53107092
public <T> void scheduleUpdateAfterOnActivityResult(T data, Observer<T> observer) {
    final MutableLiveData<T> liveData = new MutableLiveData<>();
    liveData.observe(this, new Observer<T>() {
        @Override
        public void onChanged(@Nullable final T v) {
            observer.onChanged(v);
            liveData.removeObserver(this);
        }
    });
    liveData.postValue(data);
}

then in onActivityResult call scheduleUpdateAfterOnActivityResult():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE_XXXX && data != null) {
        scheduleUpdateAfterOnActivityResult(data, bundle -> {
            // do something
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}


来源:https://stackoverflow.com/questions/53104670/data-binding-xml-not-updating-after-onactivityresult

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!