写点什么

[译] 使用 MODEL-VIEW-INTENT 第四部分 — 独立 UI 组件 (1)

用户头像
Android架构
关注
发布于: 24 分钟前

<LinearLayout><com.hannesdorfmann.SelectedCountToolbarandroid:id="@+id/selectedCountToolbar"android:layout_width="match_parent"android:layout_height="wrap_content"/>


<com.hannesdorfmann.ShoppingBasketRecyclerViewandroid:id="@+id/shoppingBasketRecyclerView"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/></LinearLayout>


但是如何使这些组件进行相互间通信呢?显然每个组件有它自己的 Presenter:selectedCountPresenter shoppingBasketPresenter。这是父子关系吗?不,两者都仅仅观察同一个 Model(从相同的业务逻辑里获


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


取更新):



public class SelectedCountPresenterextends MviBasePresenter<SelectedCountView, Integer> {


private ShoppingCart shoppingCart;


public SelectedCountPresenter(ShoppingCart shoppingCart) {this.shoppingCart = shoppingCart;}


@Override protected void bindIntents() {subscribeViewState(shoppingCart.getSelectedItemsObservable(), SelectedCountView::render);}}


class SelectedCountToolbar extends Toolbar implements SelectedCountView {


...


@Override public void render(int selectedCount) {if (selectedCount == 0) {setVisibility(View.VISIBLE);} else {setVisibility(View.INVISIBLE);}}}


ShoppingBasketRecyclerView 的代码看起来不错,有很多相同的地方,因此我忽略掉这些相同的地方了。然而,如果我们仔细观察 selectedCountPresenter 我们会注意到这个 Presenter 与 shoppingcart 耦合。我们想要使用这个 UI 组件可以在我们 App 的其他的页面使用,让这个组件变的可复用,我们需要移除这个依赖,这事实上是一个简单的重构:这个 Presenter 得到一个 Observable 作为 Model 的构造函数取代原来的 ShoppingCart:


public class SelectedCountPresenterextends MviBasePresenter<SelectedCountView, Integer> {


private Observable<Integer> selectedCountObservable;


public SelectedCountPresenter(Observable<Integer> selectedCountObservable) {this.selectedCountObservable = selectedCountObservable;}


@Override protected void bindIntents() {subscribeViewState(selectedCountObservable, SelectedCountToolbarView::render);}}


就是这样,任何时候,当我们想要显示当前 item 选择数量的时候,我们可以用这个 SelectedCountToolbar 组件。这个组件在购物车,可以记物品项的数量。但是,这个 UI 控件也可以用在你 App 里完全不同的情景下。此外,这个 UI 控件可以放在一个独立库中,并且在其他的 app 中使用,比如一个能显示选择多少张照片的 app。


Observable<Integer> selectedCount = photoManager.getPhotos().map(photos -> {int selected = 0;for (Photo item : photos) {if (item.isSelected()) selected++;}return selected;});


return new SelectedCountToolbarPresnter(selectedCount);

总结

这篇博客的目的是为了演示,父子关系通常来说是不需要的,并且可以避免,通过简单的观察你业务逻辑的相同部分。 不用 EventBus, 不需要从你的父 Activity/Fragment 中 findViewById(),不需要 Presenter.getParentPresenter() 或者其他需要其他的解决办法。仅仅需要观察者模式。伴有 RxJava 的帮助,RxJava 是实现观察者模式的基础,我们可以很轻松的构建这样的响应式 UI 组件。

另外的思考

通过与 MVP 或者 MVVM 的对比,在 MVI 我们强制(用一种激进的方法)让业务逻辑驱动一定的组件状态。故在使用 MVI 上有经验的开发者总结出下面结论:


如果一个 view 状态是另一个组件的 model?如果 view 的状态在一个组件中发生了变化,这个变化是另一个组件的意图,那么如何处理?


例子:


Observable<Integer> selectedItemCountObservable =shoppingBasketPresenter.getViewStateObservable().map(items -> {int selected = 0;

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
[译]使用 MODEL-VIEW-INTENT 第四部分 — 独立 UI 组件 (1)