Как наблюдать жилтаты с множественным наблюдением за правильным способом в Android? - PullRequest
2 голосов
/ 24 сентября 2019

У меня есть Активность, и она превратится во фрагмент-А, а затем превратится во фрагмент-Б, как показано ниже.

Activity -> Fragment-A -> Fragment-B

ситуация 1

Эти два фрагмента показывают одни и те же LiveData для отображения snackBar, как показано ниже.

viewModel.responseData.observe(this, Observer {
            it.getContentIfNotHandled()?.let {
            showSnackBar(it)
}

livedata в viewModel:

var responseData = MutableLiveData<Event<String>>()
responseData.value = Event("$message")

Ошибка: Когда я использую вышеуказанный код.Это только показывает snackBar в фрагмент-A . фрагмент-B не может получить значение.

ситуация 2

Когда я изменяю код на следующий

viewModel.responseData.observe(this, Observer {
            showSnackBar(it.peekContent())
})

Оба фрагмента могут получить значение.

Ошибка:

После закрытия фрагмента и повторного поворота.Он показывает снэк-бар, потому что значение responseData все еще существует.Но я не отправил сообщение.

Event ссылка на класс от Google выглядит следующим образом:

/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package bbin.mobile.ballbet.support

import androidx.lifecycle.Observer
import timber.log.Timber

/**
 * Used as a wrapper for data that is exposed via a LiveData that represents an event.
 */
open class Event<out T>(private val content: T) {

    var hasBeenHandled = false
        private set // Allow external read but not write

    /**
     * Returns the content and prevents its use again.
     */
    fun getContentIfNotHandled(): T? {
        return if (hasBeenHandled) {
            null
        } else {
            hasBeenHandled = true
            content
        }
    }

    /**
     * Returns the content, even if it's already been handled.
     */
    fun peekContent(): T = content
}

/**
 * An [Observer] for [Event]s, simplifying the pattern of checking if the [Event]'s content has
 * already been handled.
 *
 * [onEventUnhandledContent] is *only* called if the [Event]'s contents has not been handled.
 */
class EventObserver<T>(private val onEventUnhandledContent: (T) -> Unit) : Observer<Event<T>> {
    override fun onChanged(event: Event<T>?) {
        event?.getContentIfNotHandled()?.let {
            onEventUnhandledContent(it)
        }
    }
}

Я хочу, чтобы фрагмент показывал правильное сообщение snackBar для них.

Как соблюдать livedata для нескольких фрагментов для правильного пути в Android?

Заранее спасибо.

1 Ответ

0 голосов
/ 24 сентября 2019

Вы правильно наблюдаете за LiveData, именно так устроен класс Event.

Когда вы выполните

viewModel.responseData.observe(this, Observer {
            it.getContentIfNotHandled()?.let {
            showSnackBar(it)
}

getContentIfNotHandled, вы вернете контент только один раз, покановое значение установлено снова.Если FragmentA потребляет это первое, FragmentB не сможет использовать то же значение.Это причина того, что peekContent работает, так как он всегда будет возвращать текущее значение, даже если событие было использовано.

Если есть веская причина, по которой вам нужно показывать это сообщение Snackbar в обоих фрагментах, я предлагаю вамнаблюдать за различными LiveData экземплярами для каждого фрагмента.

Вы можете сделать это, возвращая новый LiveData<Event<String>> каждый раз, когда вызывается viewModel.getResponseData().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...