【问题标题】:How to control ListView with MVP Pattern for Android如何使用适用于 Android 的 MVP 模式控制 ListView
【发布时间】:2014-09-11 13:01:03
【问题描述】:

我目前正在使用 MVP 模式开发一个 Android 应用程序。

当我尝试开发一个 Activity 时,我应该使用 ListView。所以我将适配器用于 ListView。但我听说 Adapter 类似于 Presenter on MVP Pattern。

我认为如果 Apdater 与 Presenter 相似,那么我应该使用 Presenter 来更新 ListView 而不是 Adapter。

遇到这种情况,如何开发ListView?只使用适配器并继续使用 MVP 模式?

感谢您的阅读。

【问题讨论】:

标签: android listview mvp listadapter


【解决方案1】:

适配器是视图的一部分。事实上,所有的 Android 依赖都应该是视图的一部分。 将适配器与您的模型和演示者隔离开来是一项艰巨的任务。 I have released a library called PaperKnife for this purpose.

您可以使用 PaperKnife 将适配器与模型和演示者层分离。请按照以下步骤操作:

  1. 使用CellElement接口抽象模型层。您的视图层不需要知道您的模型。

  2. 创建一个类来为您的行视图提供信息。您可以使用您的演示者。实现类CellDataProvider 并创建方法来提供所有信息。使用 @DataSource("DataId") 注释您的提供程序方法以执行映射。您的数据方法接收模型类的实例。例如:

    public class SamplePresenterImpl implements SamplePresenter, CellDataProvider {
        @DataSource("Title")
        public String getTitle(Item item) {
            return item.getTitle();
        }
        // etc.
    }
    
  3. 在您的适配器中创建一个ViewHolder 并实现CellViewHolder 接口。创建方法来管理视图并使用DataTarget("DataId")

    static class ViewHolder extends CellViewHolder {
        @DataTarget("Title")
        public String setTitle(String title) {
            mTextViewTitle.setText(title);
        }
    }
    
  4. 在您的适配器getView 方法中执行映射:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // etc.
        PaperKnife.map(mList.get(position))
                        .dataProvider(mCellDataProvider)
                        .into(viewHolder);
        return convertView;
    }
    

这样你的视图层只知道CellElement接口,你的presenter负责向你的适配器提供数据。

【讨论】:

    【解决方案2】:

    是的,适配器应该是 MVP 模式中的 P 组件。事实上,ListViews 几乎是用 MVP 编写的——getView() 函数需要在每次调用时设置视图的所有值,这几乎是演示者必须做的定义。虽然它也很容易以 MVC 类型的方式使用它——只需在 View 上使用 getView 调用函数,将模型传递给它并在 Views 中完成这项工作。所以无论哪种方式都行得通,只需选择您的偏好即可。

    如果您确实使用具有复杂列表行的 MVP 模型,我喜欢将这些行设为自定义复合视图,并在其上放置更多描述性函数名称,而不是使用 listRow.findViewById(R.id.textView).setText (filename) 我会去 listRow.setFilename(filename) 并让视图知道如何处理它。这有点模糊了 MVP 和 MVC 的界限,但我发现它很好地平衡了适配器的可读性和避免纯 MVC 有时带来的一些尴尬。

    【讨论】:

    • 我不这么认为。 MVP、MVC是架构模式,适配器是设计模式。它们不应该相同。查看讨论stackoverflow.com/a/4243407/3304280
    • 你表现得好像设计和架构之间存在差异。没有,它们是同义词
    • 不,它们不是同义词,设计模式基本上是使用面向对象的软件开发来解决问题并使代码或模式可重用,而架构模式旨在处理应用程序的整个结构。它们肯定是不同的。您的回答具有误导性和错误性。
    • Adapter 是 MVP 中 V 的一部分。首先,它是 Android 库的一部分,当在 P 中您想要对 Android 库类做的唯一事情就是可选地将它们作为参数接收时,这样您以后可以在单元测试时轻松地模拟它们。其次,适配器具有创建和显示布局项的方法,而在 P 中您不应该考虑显示数据,而应该考虑控制它。下面由@albertovecina 提供的答案应该被接受。
    • @DarekDeoniziak 你对 MVP 的概念太具体了。您的描述是 MVP 的一种特定实现。一般来说,MVP 需要一个数据对象、一个或多个单独的视图对象,以及一个操纵视图以显示数据的演示者对象。仅此而已。它与单元测试、junit 或其他无关。
    【解决方案3】:

    如果该活动中只有一个列表视图,则无需编写单独的演示者,因为适配器实际上是作为列表视图的演示者工作的。但是,如果您有除 ListView 之外的其他 UI 组件需要更新,那么您必须为这些 UI 组件编写单独的 Presenter。

    【讨论】:

      【解决方案4】:

      Android 应用程序基本上是围绕模型-视图-控制器 (MVC) 构建的 - MVP 听起来很像,尽管我以前没有听说过这个术语。活动充当控制器的角色,XML 视图就是这样(尽管您可以在 Activity 中以编程方式构建它们 - 在 XML 中更容易和更简单),以及您自己编写的模型。所以是的,这个模型非常实用。

      您可能不太了解此设计模型的一个可能原因是,Android 框架会强制您将视图分开。因为移动设备上的应用程序往往很小,人们不倾向于使用完整的 MVC;他们倾向于视图和动作层,其中动作层完成了模型的大部分(小)工作。

      如果您正在编写一个跨平台应用程序,您可能希望查看一个四层方法:视图、操作、业务逻辑和模型。视图和操作层将是特定于平台的,而业务逻辑和模型不会改变。基本上,您将演示者和用户交互拆分到操作层,该层调用业务逻辑层来执行用户想要的操作。

      【讨论】:

      • MVP 与 Android 版本的 MVC 不同。你可能认为 Activity 是 MVC 中的“C”,但 Activity 是 MVP 中的“V”。请参阅我上面对这个问题的评论。 Android 中 MVP 的想法是将任何业务逻辑从 Activity 中分离出来——新的类成为 Presenter。 Activity(视图)应该非常薄——它只处理特定于 Android 的东西,如 findViewById、getText、setText、点击侦听器等。这种分离的一个原因是为了更容易理解和对 Presenter 进行单元测试:它可以是仅使用 JVM 进行测试 - 不需要模拟器或设备。
      • @G.Lombard Adapter 在 MVP 中属于哪里?在活动/片段(视图)中?还是演示者?自定义适配器依赖于 android.* 导入 - 那么在演示器中使用它会导致问题吗?
      • @ZakTaccardi MVP 背后的想法之一是对您的代码进行单元测试(Presenters)。所以你是绝对正确的,因为适配器依赖于 andriod。* 我猜适配器应该是一个视图而不是演示者。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      相关资源
      最近更新 更多