嵌套的RecyclerViews MVP实现

时间:2017-03-19 17:17:13

标签: android android-recyclerview mvp

我想创建一个具有嵌套水平RecyclerView的垂直RecyclerView的应用。在这种情况下,我不明白如何正确使用MVP模式。 MVP"规则"说它应该只是一个屏幕视图。

enter image description here

我的View界面:

public interface ViewLayer {
    void showProductsInCategory(int categoryId, List<ProductModel> productList, PresenterLayer presenter);

    void showCategories(List<CategoryModel> categoryItemList, PresenterLayer presenter);
}

主讲人:

public interface PresenterLayer {
    void onViewReady();
}

型号:

public interface InteractorLayer {
    void getProducts(int categoryId);

    void getCategories();
}

模型监听器接口:

public interface InteractorListener {
    void onProductsLoaded(int id, List<ProductModel> products);

    void onCategoriesLoaded(List<CategoryModel> categories);
}

CategoryModel:

public class CategoryModel {
    private String categoryName;
    private List<ProductModel> productList;

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public List<ProductModel> getProductList() {
        return productList;
    }

    public void setProductList(List<ProductModel> productList) {
        this.productList = productList;
    }
}

所以我必须通过RecyclerView选择每个嵌套categoryId来将数据添加到其适配器。我可以为每个水平RecyclerView

创建单独的Model-View-Presenter接口

UPD:

一步一步

1)MainActivity.onCreate来电presenter.onViewReady()

2)演示者调用interactorLayer.getCategories()

3)模型调用InteractorListener.onCategoriesLoaded(List<CategoryModel> categories)

4)演示者调用ViewLayerMainActivityshowCategories(List<CategoryModel> categoryItemList, PresenterLayer presenter)

5)MainActivitycategoryItemList设置为外部RecyclerView的适配器。现在每个categoryItem都有null productList

6)在onCategoriesLoaded(...) Presenter在每个类别的周期中调用模型ViewLayer.showCategories(...)之后的方法InteractorLayer.getProducts(i)

7)在productListPresenter次来电ViewLayer showProductsInCategory(...) MainActivity

之后

8)Adapter获取主RecyclerView的{​​{1}},获取一个类别项并为其设置productList

9)MainActivity来电Adapter&#39; s notifyDataSetChanged()

10)当RecyclerView调用

时,内部productList设置新的onBinding

我觉得它非常复杂。我该怎么办?

UPD 03/24/2017

源代码:https://github.com/Lex74/ProductsShop

1 个答案:

答案 0 :(得分:4)

首先,我想说的是,我并不认为自己是MVP大师,而是一个努力理解模式的人,

我最喜欢的MVP参考:来自Uncle Bob博客的The Clean Architecture

根据这篇博文,有一些名为依赖规则

  

... 源代码依赖只能指向内部。内圈中没有任何东西可以对外圈中的某些东西一无所知......

例如,Presenter课程不需要了解RecyclerViewRecyclerView.Adapter的任何内容。它需要一些interface来将信息传递给外层。

interface的方法取决于用例:使用List,希望能够

  • 传递对整个数据的引用ListshowCategories()
  • 刷新单个列表项(showProductsInCategory()

    所以我认为依赖规则说,ViewLayer接口必须提供满足[模型层和 Presenter 需求的方法层。作为演示者,我根本不在乎查看是否有ListView或者根本不是View而是而是声音和振动信号的某种组合。

    另一方面,View类似乎完全可以知道其Presenter类的名称(和方法),所以PresenterLayer接口可能不是必须具备的。

    完全取决于查看如何向用户提供数据。嵌套的View结构仍然只是一个复杂的View。所以我没有&#39;认为需要提供嵌套的interface s。

    在某些使用嵌套List的情况下,Presenter可能需要一种方法来更新内部List的内容,例如showSingleProductInCategory(ProductModel product, int categoryPosition, int productPosition)

    另一个有趣的问题:谁保留(并可能修改)数据?在我看来, Presenter 负责数据,它只应将对数据的引用传递到视图层或通知它更改。适配器不应该有权修改原始数据列表,Presenter永远不应该问适配器&#34;有多少项?&#34;而且我不太喜欢两个单独数据列表的想法。各种通知......方法的名称似乎表明我在那里的正确轨道。

    这意味着Presenter将始终保留原始数据List。如果数据发生变化,Presenter将更新其数据(可能是clear()和&#34;复制新项目&#34;也可能更细粒度,具体取决于{{1} }提供)之后,ProductLoader将通过Presenter界面通知Adapter

    链接到zip file with the modified Java classes

    编辑

    不知何故,我怀疑一个屏幕&#34;一个查看。适用于Android。想象一下典型的Master-Detail情况。如果屏幕很大,您将需要使用空格并同时显示ViewLayer个。

    因此,如果每Fragment有一个查看(以及一个演示者),一切都适用于所有类型的屏幕。它取决于屏幕尺寸,由Fragment来管理Activity

    我已经解释过,我希望某些FragmentAdapter的{​​{1}}实现ListView作为{的回调所需的RecyclerView {1}}。 (作为回调角色的所有interface都可以将信息传递给Presenter无论如何)

    另一方面,Fragment可能包含几组数据。其中一些可能以某种方式相关(如某个特定艺术家的所有歌曲),其他(所有这些广告......)而不是。 演示者需要方法来告诉查看向用户显示的内容:艺术家的一种方法,广告的一种方法等。

    因此,如果我的应用程序包含少量Adapter个,则Fragment将包含

    等方法
    Fragment

    ...而interface会期望某个类在其void showAdvertisement(AdObject ad); void showArtistInfo(Artist artist); 中实现此特定Presenter。 (加上歌曲的interface),我Constructor为所有非收藏数据实施Adapter

    在包含多个应用的​​项目中,可以考虑使用通用Fragment (一个用于任何类型的详细信息,一个用于收集)。然后会有一个方法interface,上面示例中的interface会期望广告的一个回调和艺术家信息的回调:

    showData(T data)

    然后在Presenter中写一个:

    MyPlaylistPresenter (DetailInterface<AdObject> adCallback, DetailInterface<Artist> artistCallback, CollectionInterface<Song> songsCallback){...}
    

    有点像Lego :),但总共少于Fragment个类。并且基本相同的方法在整个项目中具有相同的名称,因此我认为它有助于可维护性。

    现在谈谈你的另一个问题:

    如果您的应用在客户端有模型,那么我认为您是对的。 另一方面,有些项目中模型是后端的一部分。然后 Presenter 将是合理的选择。