it-swarm.com.de

Wie lösche ich den gespeicherten Wert von LiveData?

Laut LiveData-Dokumentation :

Die LiveData-Klasse bietet die folgenden Vorteile:

...

Immer aktuelle Daten: Wenn ein Lebenszyklus erneut beginnt (z. B. eine Aktivität, die vom Back-Stack in den Startzustand zurückversetzt wird), erhält sie die neuesten Standortdaten (falls noch nicht geschehen).

Aber manchmal brauche ich diese Funktion nicht. 

Ich habe beispielsweise LiveData in ViewModel und Observer in Activity:

//LiveData
val showDialogLiveData = MutableLiveData<String>()

//Activity
viewModel.showMessageLiveData.observe(this, Android.Arch.lifecycle.Observer { message ->
        AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK") { _, _ -> }
                .show()
    })

Nach jeder Umdrehung erscheint ein alter Dialog.

Gibt es eine Möglichkeit, gespeicherte Werte nach der Verarbeitung zu löschen, oder ist die Verwendung von LiveData überhaupt falsch?

22
Kamer358

Alex Antwort in den Kommentaren ist, ich denke genau, was Sie suchen. Es gibt Beispielcode für eine Klasse namens SingleLiveEvent . Der Zweck dieser Klasse wird beschrieben als:

Ein lebenszyklusbewusstes Observable, das nach .__ nur neue Updates sendet. Abonnement, das für Ereignisse wie Navigation und Snackbar-Nachrichten verwendet wird.

Dadurch wird ein häufiges Problem mit Ereignissen vermieden: bei Konfigurationsänderung (wie bei Rotation) kann ein Update ausgegeben werden, wenn der Beobachter aktiv ist . Diese LiveData ruft das Observable nur auf, wenn ein expliziter Aufruf von .__ erfolgt. setValue () oder call ().

29
Lyla

In meinem Fall hilft SingleLiveEvent nicht. Ich benutze diesen Code:

private MutableLiveData<Boolean> someLiveData;
private final Observer<Boolean> someObserver = new Observer<Boolean>() {
    @Override
    public void onChanged(@Nullable Boolean aBoolean) {
        if (aBoolean != null) {
            // doing work
            ...

            // reset LiveData value  
            someLiveData.postValue(null);
        }
    }
};
4
Final12345

Ich bin mir nicht sicher, ob es in Ihrem Fall funktionieren wird, aber in meinem Fall (Vergrößern/Verringern der Anzahl der Elemente in Room by Click auf Ansichten), entfernen Sie Observer und prüfen, ob aktive Beobachter vorhanden sind.

LiveData<MenuItem> menuitem = mViewModel.getMenuItemById(menuid);
menuitem.observe(this, (MenuItem menuItemRoom) ->{
                menuitem.removeObservers(this);
                if(menuitem.hasObservers())return;

                // Do your single job here

                });
});  
1
Jurij Pitulja

Sie müssen SingleLiveEvent für diesen Fall verwenden

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

    private val pending = 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> { t ->
            if (pending.compareAndSet(true, false)) {
                observer.onChanged(t)
            }
        })
    }

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

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

    companion object {
        private const val TAG = "SingleLiveEvent"
    }
}

Und in Ihrer Viewmodel-Klasse erstellen Sie ein Objekt wie:

 val snackbarMessage = SingleLiveEvent<Int>()
1
Ankit Bisht

Die beste Lösung, die ich gefunden habe, ist live event library was perfekt funktioniert, wenn Sie mehrere Beobachter haben:

class LiveEventViewModel : ViewModel() {
    private val clickedState = LiveEvent<String>()
    val state: LiveData<String> = clickedState

    fun clicked() {
        clickedState.value = ...
    }
}
0
Morteza Rastgoo

Wenn Sie eine einfache Lösung benötigen, probieren Sie diese aus:

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

    override fun observe(owner: LifecycleOwner, observer: Observer<in T?>) {
        super.observe(owner, Observer { t ->
            if (t != null) {
                observer.onChanged(t)
                postValue(null)
            }
        })
    }
}

Verwenden Sie es wie ein reguläres MutableLiveData

0
Nynuzoud