Created
January 23, 2017 23:31
-
-
Save sockeqwe/92230cad2a9f56decacd5993df93d1ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PersonsModel { | |
// In a real application fields would be private | |
// and we would have getters to access them | |
final boolean loading; | |
final List<Person> persons; | |
final Throwable error; | |
public(boolean loading, List<Person> persons, Throwable error){ | |
this.loading = loading; | |
this.persons = persons; | |
this.error = error; | |
} | |
// ... getters ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PersonsActivity extends MviActivity<PersonsPresenter> implements PersonsView { | |
private PersonsAdapter adatper; | |
// ... other things like onCreate() etc. | |
@Override public Observable<Boolean> load() { | |
return Observable.just(true); | |
} | |
@Override public void render(PersonsModelWithDiff viewState){ | |
if (viewState.isLoading() ) { | |
// Show Loading | |
loadingView.setVisisbility(View.VISIBLIE) | |
erroView.setVisibility(View.GONE); | |
recyclerView.setVisibility(View.GONE); | |
} else if (viewState.getError() != null) { | |
// Show Error | |
loadingView.setVisisbility(View.GONE) | |
erroView.setVisibility(View.VISIBLE); | |
recyclerView.setVisibility(View.GONE); | |
} else if (viewState.getPersons() != null ){ | |
// Show Content (RecyclerView) | |
adapter.setPersons(viewState.getPersons()); | |
viewState.getDiffResult().dispatchTo(adapter); | |
loadingView.setVisisbility(View.GONE) | |
erroView.setVisibility(View.GONE); | |
recyclerView.setVisibility(View.VISIBLE); | |
} else { | |
throw new IllegalStateException("Don't know how to render "+viewState); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This class is responsible to load a list of persons from backend | |
class PersonsInteractor { | |
private Backend backend; | |
public Observable<PersonsModel> loadPersons(){ | |
return backend.getPersons() // Executes an http call i.e. with retrofit; returns Observable<List<Person>> | |
.map( persons -> new PersonModel(false, persons, null) ) | |
.startWith( new PersonModel(true, null, null) ) // Indicates Loading | |
.onErrorReturn( error -> new PersonModel(false, null, error) ); // Indicates Error | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PersonsModelWithDiff { | |
// In a real application fields would be private | |
// and we would have getters to access them | |
final boolean loading; | |
final List<Person> persons; | |
final DiffResult result; | |
final Throwable error; | |
public(PersonModel originalModel, DiffResult diffResult){ | |
this.loading = originalModel.getLoading(); | |
this.persons = originalModel.getPersons(); | |
this.error = originalModel.getError(); | |
this.diffResult = diffResult; | |
} | |
// ... getters ... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PersonsPresenter extends MviBasePresenter<PersonsView, PersonsModelWithDiff> { | |
private final PersonsInteractor interactor; | |
// This will interally hold a list to the previous List<Person>; | |
// However, that means that the function using this callback is not pure anymore (because it is a sideeffect to hold internally previous List<Person> | |
// To make it pure one could use RxJava scan operator. | |
private final DiffUtil.Callback callback; | |
public void bindIntents(){ | |
Observable<PersonsModelWithDiff> observable = intent(PersonsView::load) | |
.flatMap( ignored -> interactor.load() ) | |
.map( personModel -> { | |
if (personModel.getPersons() != null) | |
return new PersonsModelWithDiff(personModel, DiffUtils.calculateDiff(callback)); | |
else | |
return new PersonsModelWithDiff(personModel, null); | |
}) | |
.subscribeOn(Schedulers.io()) | |
.observeOn(AndroidSchedulers.mainThread()); | |
subscribeViewState(observable, PersonsView::render); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment