Giter VIP home page Giter VIP logo

liveevent's People

Contributors

aasitnikov avatar hadilq avatar kcrimi avatar ujavid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

liveevent's Issues

[Feature Request] Encapsulation

Hi,
I always used Event wrapper for handling actions. But I found this solution as a better approach.

However It would be great if you add encapsulation support. I mean for LiveData itself we have two classes: LiveData and MutableLiveData and for example we use them in a ViewModel like below:

private val _isEnabled = MutableLiveData<Boolean>(false)
val isEnabled: LiveData<Boolean>
    get() = _isEnabled

With this approach we cannot post values inside view to the LiveData we observing. So in this library we can have two classes like LiveEvent and MutableLiveEvent that extends from LiveEvent. This two functions (postValue() and setValue()) must be protected inside LiveEvent class and public inside MutableLiveEvent.

Event not sent

Hi there.
I'm sorry if this is vague but unfortunately I don't have much time to spend on this at this stage.
Anyway, I swapped my SingleLiveEvent class taken from the one on the google repo for yours since I needed the same functionality but with multiple observers.
All I did is a direct copy paste into the SingleLiveEvent class with your code in, and the very first event I use in the class ( it's on the main activity to decie whther to go to the login screen or Home ) never fired at all, so the app just hangs there.
I've left the exact same code as from SingleLiveEvent, only swapped out the code in the class, and it doesn't work.
I don't know if there's something obvious I'm missing...

Api 23 min?

Try run this code, but notify min api 23

    private val observers = ArraySet<ObserverWrapper<in T>>()

In actuality I use this code extract SO

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
}

observeForever is not implemented

    @MainThread
    override fun observeForever(observer: Observer<in T>) {
        val wrapper = ObserverWrapper(observer)
        observers.add(wrapper)
        super.observeForever(wrapper)
    }

is not implemented.

So LiveEvent is not possible to use source of MediatorLiveData.
(MediatorLiveData uses observeForever)

[Feature Request] Optional behavior like Jose Alcerreca's EventWrapper class

Its great now that we can add multiple observers to the LiveEvent object, But in most cases we want to act as we added a single observer. For example imagine that we accidentally added observer in onViewCreated of the fragment and we did not removed the observer. So after going to another fragment and getting back actions will be called twice (Or there can be another similar cases). I think it is good to have such a SingleLiveEvent class that only delivers data for the first observer in such cases.

Thanks

Make inheritance possible

Defining the class as open would allow inheritance, which is something that is not possible currently. For debugging reasons I am overriding the setValue method and adding logging there, something which is not possible with this implementation. I know I can easily log this elsewhere but more substantial changes would suffer from this.

Multiple instances of observer added if Observe or ObserveForever is called multiple times

If LiveEvent.observe or LiveEvent.observeForever is called multiple times, it will add the same observer multiple times. This is because ObserverWrapper is added around the observer and this negates the usefulness of having the ArraySet of observers since a unique entry is added each time.

data.observeForever(dataObserver)
data.observeForever(dataObserver)
data.observeForever(dataObserver)

data.postValue(value)

This results in dataObserver being notified 3 times. When using typical LiveData, adding the same observer (perhaps accidently) multiple times would not be an issue.

<in T> giving compile time error

Type mismatch.
Required:
Observer<T!>
Found:
LiveEvent.ObserverWrapper

Is it related to my Kotlin version (1.3.50) ?
Anyway removing contravariancy from types and parameters helped to compile.

LiveEvent and configuration changes

I was under the impression that using LiveEvent, we would be able to use these events to trigger dialogs in a Fragment. E.g.

class MyFragment : Fragment(){
    override fun onCreateView(inflater: LayoutInflater,
                              container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        val binding = // inflate view using Databinding
        binding.viewModel = // some viewModel
        viewModel.events().observe(viewLifecycleOwner, Observer { event ->
                showDialog(event)
        })
        return binding.root
    }
}

This is the ViewModel:

class MyViewModel : ViewModel(){
    private val events = MutableLiveData<DialogEvent>()
    fun events(): LiveData<DialogEvent> = events.toSingleEvent()

    fun onClick() = events.postValue(DialogEvent)
}

object DialogEvent

So, whenever I click a button, a dialog is shown.
However, when I rotate the screen, the dialog is shown again.
This makes sense, because on orientation change, the observer is removed, added again, and will receive the latest value...

Am I wrong that LiveEvent can be used in these scenario's?
Or am I missing something obvious?

Observer registered after LiveEvent already has value is not executed

If the LiveEvent's setValue is called before observe and there is no observer to consume the event the next registered observer is not receiving the event as well because pending is by default false.

This is maybe a deliberate decision but I find it a huge weakness of the design.

Value set before observing question

Do we need to resend value that was set before we observe liveevent?

For example we set value to our live data and only after this we subscribe with observer.
With current implementation we will not receive current value to our observer

val event = LiveEvent<Boolean>()
event.value = true
event.observe(this, Observer {
           // no trigger
})

If there is no support for Voids we can check value in observe function and send it to newly subscribed observers if it's not null.

LiveEvent class should not inherit from MediatorLiveData?

Currently, LiveEvent class inherits from MediatorLiveData. However, when using addSource(), the correct result is not obtained.

For example, if you rewrite the following test code, the test will fail.

@Test
fun `observe after emit event`() {
// Given
owner.create()
val event = "event"
liveEvent.value = event
liveEvent.observe(owner, observer)
// When
owner.start()
// Then
if (config == LiveEventConfig.Normal) {
verify(observer, never()).onChanged(event)
} else {
verify(observer, times(1)).onChanged(event)
}
}

@Test
fun `observe after emit event`() {
    // Given
    val mutableLiveData = MutableLiveData<String>()
    liveEvent.addSource(mutableLiveData) {
        liveEvent.value = it
    }
    owner.create()
    val event = "event"
    mutableLiveData.value = event
    liveEvent.observe(owner, observer)

    // When
    owner.start()

    // Then
    if (config == LiveEventConfig.Normal) {
        verify(observer, never()).onChanged(event) // This test does not pass
    } else {
        verify(observer, times(1)).onChanged(event)
    }
}

Should the LiveEvent class be an inheritance of MutableLiveData?

3 tests are failing

First of all, thank you for the community contribution with your LiveEvent, @hadilq !

I noticed that 3 tests are failing:

  • observe after remove multi owner
  • observe after remove owner
  • observe after remove

implement postValue

One of the most common usages of LiveData from a ViewModel is through the postValue method which doesn't seem to be implemented.

Unexpected triggering

It seems to be triggered when lifecycle goes to STARTED state. How do I prevent this behaviour and make it triggered only if event happened when observer is active?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.