有可能在Java中为Android实现模型-视图-控制器模式吗?

或者它已经通过活动实现了吗?或者有没有更好的方法来实现Android的MVC模式?


当前回答

厌倦了Android上的MVx灾难,我最近做了一个提供单向数据流的小库,类似于MVC的概念:https://github.com/zserge/anvil

基本上,您有一个组件(活动、片段和视图组)。在内部定义视图层的结构和样式。此外,您还可以定义数据应该如何绑定到视图。最后,您可以在同一位置绑定侦听器。

然后,一旦你的数据被改变——全局的“render()”方法将被调用,你的视图将会被最新的数据巧妙地更新。

下面是一个组件的例子,为了代码紧凑,组件中包含了所有内容(当然,模型和控制器可以很容易地分开)。这里“count”是一个模型,view()方法是一个视图,“v -> count++”是一个控制器,它监听按钮点击并更新模型。

public MyView extends RenderableView {
  public MyView(Context c) {
      super(c);
  }

  private int count = 0;

  public void view() {
    frameLayout(() -> {              // Define your view hierarchy
      size(FILL, WRAP);
      button(() -> {
          textColor(Color.RED);      // Define view style
          text("Clicked " + count);  // Bind data
          onClick(v -> count++);     // Bind listeners
      });
    });
  }

使用分离的模型和控制器,它看起来像:

button(() -> {
   textColor(Color.RED);
   text("Clicked " + mModel.getClickCount());
   onClick(mController::onButtonClicked);
});

在这里,点击每个按钮的数量都会增加,然后“render()”将被调用,按钮文本将被更新。

如果使用Kotlin: http://zserge.com/blog/anvil-kotlin.html,语法将变得更加舒适。此外,对于没有lambdas的Java还有其他语法。

这个库本身是非常轻量级的,没有依赖关系,不使用反射等等。

(声明:我是这个库的作者)

其他回答

Android上的动作、视图和活动是与Android UI一起工作的内置方式,是模型-视图-视图模型(MVVM)模式的实现,它在结构上与模型-视图-控制器相似(在同一家族中)。

据我所知,没有办法打破这个模式。这可能是可以做到的,但是您可能会失去现有模型的所有好处,并且必须重写自己的UI层以使其正常工作。

令人惊讶的是,这里没有一个帖子回答这个问题。它们要么太笼统,模糊,不正确,要么没有解决在android中的实现。

在MVC中,View层只知道如何显示用户界面(UI)。如果需要任何数据,则从Model层获取。但是视图并不直接要求模型去查找数据,它是通过控制器来做的。因此控制器调用模型为视图提供所需的数据。一旦数据准备好了,控制器就通知视图,可以从模型中获取数据了。现在视图可以从模型中获取数据。

这个流程可以总结如下:

值得注意的是,视图可以通过控制器(也称为被动MVC)了解模型中数据的可用性,或者通过向模型注册可观察对象来观察模型中的数据,这就是活动MVC。

在实现部分,首先想到的是视图应该使用什么android组件?活动还是片段?

答案是没有关系,两者都可以使用。View应该能够在设备上呈现用户界面(UI),并响应用户与UI的交互。Activity和Fragment都为此提供了所需的方法。

在本文使用的示例应用程序中,我使用了Activity作为视图层,但也可以使用Fragment。

完整的示例应用程序可以在我的GitHub repo的“mvc”分支中找到。

我还通过一个例子说明了在android中使用MVC架构的利弊。

对于那些感兴趣的人,我已经开始了一系列关于android应用程序架构的文章,在这里我比较了不同的架构,即MVC, MVP, MVVM,通过一个完整的工作应用程序开发android应用程序。

使用布局、资源、活动和意图创建Android UI是MVC模式的实现。请参阅以下链接了解更多信息- http://www.cs.otago.ac.nz/cosc346/labs/COSC346-lab2.2up.pdf

PDF镜像

厌倦了Android上的MVx灾难,我最近做了一个提供单向数据流的小库,类似于MVC的概念:https://github.com/zserge/anvil

基本上,您有一个组件(活动、片段和视图组)。在内部定义视图层的结构和样式。此外,您还可以定义数据应该如何绑定到视图。最后,您可以在同一位置绑定侦听器。

然后,一旦你的数据被改变——全局的“render()”方法将被调用,你的视图将会被最新的数据巧妙地更新。

下面是一个组件的例子,为了代码紧凑,组件中包含了所有内容(当然,模型和控制器可以很容易地分开)。这里“count”是一个模型,view()方法是一个视图,“v -> count++”是一个控制器,它监听按钮点击并更新模型。

public MyView extends RenderableView {
  public MyView(Context c) {
      super(c);
  }

  private int count = 0;

  public void view() {
    frameLayout(() -> {              // Define your view hierarchy
      size(FILL, WRAP);
      button(() -> {
          textColor(Color.RED);      // Define view style
          text("Clicked " + count);  // Bind data
          onClick(v -> count++);     // Bind listeners
      });
    });
  }

使用分离的模型和控制器,它看起来像:

button(() -> {
   textColor(Color.RED);
   text("Clicked " + mModel.getClickCount());
   onClick(mController::onButtonClicked);
});

在这里,点击每个按钮的数量都会增加,然后“render()”将被调用,按钮文本将被更新。

如果使用Kotlin: http://zserge.com/blog/anvil-kotlin.html,语法将变得更加舒适。此外,对于没有lambdas的Java还有其他语法。

这个库本身是非常轻量级的,没有依赖关系,不使用反射等等。

(声明:我是这个库的作者)

没有一个单一的MVC模式可以遵循。MVC只是或多或少地说明了你不应该将数据和视图混为一谈,例如,视图负责保存数据,或者处理数据的类直接影响视图。

但无论如何,Android处理类和资源的方式,有时你甚至被迫遵循MVC模式。在我看来,更复杂的是那些有时负责视图,但同时又充当控制器的活动。

如果您在XML文件中定义视图和布局,从res文件夹加载资源,并且如果您或多或少地避免在代码中混合这些东西,那么您无论如何都是在遵循MVC模式。