glung/redux-java

Animating removal/addition of todos in the example apps

Closed this issue · 3 comments

In the TODO list example, you have to set the items in the adapter and call the notifyDataSetChanged method instead of one of the more specific methods (e.g. notifyItemRemoved). Note that when calling the more specific methods, it allows RecyclerView to actually perform the removal/addition/change/etc animations.

With all these unidirectional data-flow architectures, it seems they build the UI as a function of the state. I think that's a really enticing concept, but I can't see how something as simple as the issue mentioned above is supposed to work. Is there a way to fix this or is it just a limitation of the architecture?

glung commented

@grandstaish Thank you for asking, that's a great question. I'll try to give answer but I would be glad to know about other solutions - I don't pretend having the perfect answer.

Redux is a state container, it notifies the subscribers and provide the current state on change. The naïve and easy solution is too re-render everything, every time - this is what this example does.

To render the UI -as you said- here we decided to use a function of the state to build a representation of the UI. We could have use something else else and stateful. But I agree with you, it feels better when using pure functions. But then, we face the kind of problems you mentioned.

But let's not be fooled, UI are full of states and we can't go without it. When we say we remove states, we actually mean we draw boundaries for states.

In the end, these states exists, at least in the Android SDK (adapters, scrolling positions, etc).

In this case, we can use hasStateIds and getItemId from the recycler API and let the SDK manage its states and perform animations [1] for free.

Does it answer your question ?

[1] http://stackoverflow.com/questions/29566719/animation-for-change-and-remove-do-not-work-with-recyclerview

👍 to @glung's answer. Say, for example, you have a list of TODOs. What you'd want to do is add an id field to each TodoModel. Then, in your adapter, set setHasStableIds(true) in the constructor of the adapter and override getItemId to return the id from the given TodoModel at a certain position. Then, when you call notifyDataSetChanged() you don't have to manually compute the difference between the two states and manually call notifyItemRemoved/Added/etc: The RecyclerView already has prebuilt logic to do that for you :)

That answers my question, yep. Thanks. Interesting work BTW, I'll definitely be playing around a lot more with some of these concepts.