【问题标题】:Android MVP - passing string resources from the presenter to the viewAndroid MVP - 将字符串资源从演示者传递到视图
【发布时间】:2017-03-16 06:18:35
【问题描述】:

我最近开始开发具有模型-视图-演示者架构的 Android 应用。一个我一直无法找到好的解决方案的问题是从演示者传递字符串以显示在视图中。

我试图将 Android 系统依赖项排除在演示者层之外,以使单元测试更容易。当提供来自服务器或其他外部源的字符串时,这很简单。当我需要显示一个始终相同的简单错误消息时,我可以只使用像showWhateverError() 这样的方法,其中视图已经知道要使用哪个字符串资源并且可以处理加载资源本身。当我有业务逻辑来确定提供视图的字符串资源时,我可以在演示器中引用字符串资源 ID(尽管这也感觉不对)。

我还没有想出一个好的解决方案的情况是,当我需要根据一些业务逻辑显示一个有时来自服务器、有时是字符串资源的字符串时。任何想法都会有所帮助!

【问题讨论】:

    标签: android architecture android-resources mvp


    【解决方案1】:

    对于这些情况,我有额外的助手类,我称之为Formatter。我将当前状态从我的Presenter 传递给View,然后根据该状态向Formatter 询问适当的字符串。我认为一个小例子会有所帮助:

    您有一个对象,它代表您希望在视图上设置的数据。我们暂时称它为State

    public class State {
    
        private final boolean isServerString;
        private final String serverString;
    
        public State(boolean isServerString, String serverString) {
            this.isServerString = isServerString;
            this.serverString = serverString;
        }
    
        public boolean isServerString() {
            return isServerString;
        }
    
        public String getServerString() {
            return serverString;
        }
    }
    

    在您Presenter 中,您可以根据需要的任何逻辑创建它并将其传递给View

    public class MessagePresenter {
    
        private void setMessage() {
    
            // logic here
    
            State state = new State(true, "Hello from the server");
            view().setMessage(state);
        }
    }
    

    然后在您的 Activity/Fragment/ViewGroup 中,您将拥有以下内容:

    public class MyActivity extends Activity implements MessageView {
    
        private MessageFormatter formatter;
        private TextView messageTextView;
    
        @Override
        public setMessage(State state) {
    
            String message = formatter.getMessage(state);
            messageTextView.setText(message);
        }
    }
    

    如您所见,视图向Formatter 询问要在 TextView 中显示的字符串。格式化程序看起来像这样:

    public class MessageFormatter {
    
        private Context context;
    
        public MessageFormatter(Context context) {
            this.context = context;
        }
    
        public String getMessage(State state) {
    
            return state.isServerString()
                    ? state.getServerString()
                    : context.getString(R.string.default_message);
        }
    }
    

    它需要Context 作为构造函数参数,是的,它确实有一点逻辑。然而,繁重的逻辑仍然存在于Presenter 中。大多数时候它应该只是一个简单的布尔检查。

    当你创建一个Formatter 接口然后使用你的Presenter 来决定哪个 Formatter 实例化时,使用这种方法的真正威力就发挥了作用。例如,您可以创建一个HoliidayMessageFormatter 和一个DefaultMessageFormatter,这将允许您根据Presenter 中的小逻辑检查为您的应用程序提供不同的主题。

    【讨论】:

    • 我最终创建了一个 ResourceProvider 类,该类被注入到我的 Presenter 中(并在其中注入了应用程序上下文)。这样,presenter 可以在必要时访问 Android 资源,但仍然主要与 Android 类隔离。不过,您的解决方案是一个不错的选择!感谢您的想法。
    • 您的ResourceProvider 听起来是一个值得考虑的解决方案。你是直接暴露 R.string.etc 整数还是返回字符串?
    • 返回字符串
    【解决方案2】:

    错误信息可视化必须使用 View 处理!

    您的演示者必须调用相关的错误方法,例如 invalidEmail(),并且视图必须决定如何与用户交互并使用 UI 元素来显示错误。

    在某些实现中,您可能希望显示动画而不是消息!因此将消息从下层发送到视图是不正确的。

    这是一个示例代码库,可以帮助您了解有关 MVP、Dagger、测试和其他概念的更多信息:

    http://github.com/mmirhoseini/marvel

    希望对你有帮助:)

    【讨论】:

      猜你喜欢
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 2011-11-27
      • 2021-12-31
      • 2016-11-15
      • 2019-09-27
      • 1970-01-01
      相关资源
      最近更新 更多