'TO-DO added' message does not work properly
This message is shown only for the first added item. For the next items, it never comes.
Only happens for: todo-mvvm-databinding
git checkout todo-mvvm-databinding
the problem in the todo-mvvm-databinding branch comes from the way the “TO-DO added” Snackbar message is triggered.
Why it only shows for the first added item In the todo-mvvm-databinding sample, the View layer observes a LiveData (or ObservableField) in the ViewModel for showing Snackbar messages, something like:
public final ObservableField<String> snackbarText = new ObservableField<>(); or
private final MutableLiveData<String> _snackbarText = new MutableLiveData<>(); LiveData<String> snackbarText = _snackbarText; The Snackbar is shown whenever snackbarText changes.
The problem: If the ViewModel sets the same value ("TO-DO added") twice in a row, ObservableField and LiveData won’t trigger the observer the second time because the value hasn’t actually changed.
So:
First item added → "TO-DO added" set → observer triggers → Snackbar shows.
Second item added → "TO-DO added" set again → no change detected → observer does nothing → Snackbar doesn’t show.
How to fix it Option 1 – Use a one-time event wrapper This is the recommended Android Architecture Components approach:
Create an Event class:
public class Event<T> { private final T content; private boolean hasBeenHandled = false;
public Event(T content) {
this.content = content;
}
public T getContentIfNotHandled() {
if (hasBeenHandled) return null;
hasBeenHandled = true;
return content;
}
public T peekContent() {
return content;
}
} In the ViewModel:
private final MutableLiveData<Event<Integer>> _snackbarText = new MutableLiveData<>(); LiveData<Event<Integer>> snackbarText = _snackbarText;
void showTodoAddedMessage() { _snackbarText.setValue(new Event<>(R.string.todo_added)); } In the Activity/Fragment:
viewModel.snackbarText.observe(this, event -> { Integer messageRes = event.getContentIfNotHandled(); if (messageRes != null) { Snackbar.make(rootView, messageRes, Snackbar.LENGTH_SHORT).show(); } }); This way, every call to showTodoAddedMessage() emits a new Event object, even with the same message text.
Option 2 – Force value change If you don’t want an Event wrapper, you can “reset” the value before setting it again:
snackbarText.setValue(null); snackbarText.setValue("TO-DO added"); This works, but it’s hacky and not recommended for clean MVVM.
Why this only happens in todo-mvvm-databinding Other variants (like todo-mvp) often trigger Snackbars through direct view method calls in Presenters, which always run even with the same message. With Data Binding + LiveData/ObservableField, updates depend on value changes, so repeating the same value doesn’t trigger UI updates.