sockeqwe / mosby

A Model-View-Presenter / Model-View-Intent library for modern Android apps
http://hannesdorfmann.com/mosby/
Apache License 2.0
5.49k stars 841 forks source link

Mosby sample-MVI: Inconsistent intent binding behavior #232

Closed komok2013 closed 7 years ago

komok2013 commented 7 years ago

There is strange behavior in app, namely when we have only one category of products and only one product into this category instead on event pull to refresh rise another event "loadNextPage". Why?

'com.hannesdorfmann.mosby3:mvi:3.0.0-alpha2'

sockeqwe commented 7 years ago

Can you give me more information on how to reproduce the described issue? If I have understood you correctly, you are using the mvi demo app as template for your own app, right? Is your app open source so that I can take a look at it to reproduce it?

loadNextPage is triggered if the RecyclerView is scrolled to the end of the list. If the RecyclerView only contains 1 Item then "scrolled to the end of the list" is triggered immediately because you are at the end of the list. Could this explain your issue? Then this is a implementation detail and you have to find a better way to detect "scrolled to the end of RecyclerView". Alternatively your ViewState could contain information whether or not there is a next page.

btw. It's strongly recommeneded to update to com.hannesdorfmann.mosby3:mvi:3.0.2

komok2013 commented 7 years ago

Thanks for the quick response

This line solved the problem:

@Override public Observable loadNextPageIntent() { return RxRecyclerView.scrollStateChanges(recyclerView) .filter(event -> !adapter.isLoadingNextPage()) .filter(event -> event == RecyclerView.SCROLL_STATE_IDLE) .filter(event -> layoutManager.findLastCompletelyVisibleItemPosition() == adapter.getItems().size() - 1 ) .filter(event -> !swipeRefreshLayout.isRefreshing()) .map(integer -> true); }

komok2013 commented 7 years ago

And if you do not complicate. Could you give an example of combining categories if the pull-to-refresh event comes with products of an already existing category (which was already displayed).

sockeqwe commented 7 years ago

.filter(event -> !swipeRefreshLayout.isRefreshing()) I actually would like to demonstarate that pull-to-refresh and load next page is possible at the same time and the order of execution doesn't matter because the state reducer always produces the new state properly (regardless of order of exectuition).

Could you give an example of combining categories if the pull-to-refresh event comes with products of an already existing category (which was already displayed)

Do that in StateReducer. In the state reducer you take the previous state (previous list of items) and the result of the pull-to-refresh (which is also a list of items). So then simply iterate over the list of items from the previous state and only add those items from pull-to-refresh result if not already present in the list of previous state items.