Привязка данных - XML ​​не обновляется после onActivityResult - PullRequest
0 голосов
/ 01 ноября 2018

Обновление ObservableField внутри onActivityResult(..) из activity, но не отражает это значение до XML. Если я вызову executePendingBindings (), это будет работать. Но проблема в том, что существует много ObservableField, и для каждой переменной мне нужно вызвать executePendingBindings().

Кто-нибудь знает, как решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Если вы не хотите создавать SingleLiveEvent и предпочитаете хранить код обратного вызова в onActivityResult, и у вас есть базовое действие, с которого распространяются все действия, вы можете добавить метод scheduleUpdateAfterOnActivityResult к базовому активность:

// 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 /10224448/privyazka-dannyh-xml-ne-obnovlyaetsya-posle-onactivityresult
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);
}

тогда в onActivityResult вызов 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);
}
0 голосов
/ 01 ноября 2018

В файле ViewDataBinding.java есть один метод для запроса повторного связывания

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);
            }
        }
    }

Когда элемент управления входит в этот метод, mPendingRebind будет ложным, и этот метод станет истинным. mChoreographer.postFrameCallback(mFrameCallback); сделает эту переменную снова ложной, чтобы другие привязки обновили представление.

Проблема была в !state.isAtLeast(Lifecycle.State.STARTED) состоянии. Поскольку ObservableField обновляется с onActivityResult(..), текущее состояние будет Lifecycle.State.CREATED, поэтому это условие не будет выполнено и вернет этот метод без вызова mChoreographer.postFrameCallback(mFrameCallback); и mPendingRebind будет истинным. Таким образом, оставшиеся привязки не будут обновляться.

Таким образом, решение было вызвать SingleLiveEvent и наблюдать за этой переменной. Когда этот обратный вызов получен, мы должны обновить ObservableField ()

Например:

val updateObserver = SingleLiveEvent<Unit>()

Тогда наблюдайте за этим событием

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

Вызовите это событие из onActivityResult

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