简体   繁体   English

从交互器传递字符串资源以在android MVP中查看

[英]Passing string resource from interactor to view in android MVP

So, I am currently trying to implement MVP approach in android, which I am new to. 因此,我目前正在尝试在android中实现MVP方法,这是我的新手。 Now, it states that neither presenter nor the interactor class should have knowledge about android classes or components. 现在,它声明presenter和interactor类都不应该具有关于android类或组件的知识。

Makes sense to decouple the business logic from framework. 将业务逻辑与框架分离是有意义的。 Good so far. 目前很好。

However I have an presenter that implements a callback to login in interactor, that passes a string resource id. 但是,我有一个演示者,该演示者实现了用于在交互器中登录的回调,该回调传递了字符串资源ID。 The presenter passes the string res id to the view that displays error message in some form (whether a toast or a dialog). 演示者将字符串res id传递到视图,该视图以某种形式(无论是吐司还是对话框)显示错误消息。

Interactor: 交互器:

public interface SignInteractor {

void login(String email, String password, OnLoginListener loginListener);

interface OnLoginListener {

    void onLoginSuccess();

    void onLoginFail(int error);

   } 
}

Presenter: 主持人:

public interface SignInPresenterImpl {
private SignInteractorImpl mInteractor; // interactor implementation
private SignInView mSignInView; // view reference

// additional code 

    void login(String email, String password){

        mInteractor.login(email,password, new SignInteractor.OnLoginListener(){

        @Override
        public void onLoginSuccess() {
            if (mSignInView != null) {
                mSignInView.signInSuccess();
            }
        }

        @Override
        public void onLoginFail(final int error) {
            if (mSignInView != null) {
                mSignInView.showError(R.string.error);
            }
        }
        })
    }

}

Activity View: 活动视图:

SignInViewActivity implements SignInView{
   // additional code

   void showError(int resId){
    Toast.makeText(this, getString(resId), Toast.LENGTH_SHORT).show();
   }
}

However, since R file is a part of android framework, this renders the presenter and interactor to not be usable in pure java apps. 但是,由于R文件是android框架的一部分,因此这使得演示者和交互者无法在纯Java应用程序中使用。

I have gone through a lot of articles and discussions on various forums which provide various ways to achieve this. 我在各个论坛上浏览了许多文章和讨论,这些文章和讨论提供了实现此目标的各种方法。

Solutions : 解决方案:

  1. view should use method like showLoginError() and decide itself how handle the view logic. 视图应使用showLoginError()之类的方法并自行决定如何处理视图逻辑。 In this way presenter has no knowledge of android related stuff. 这样,主持人就不了解android相关的知识。

    • However, string manipulation from interactor is not possible. 但是,无法从交互器进行字符串操作。
  2. Create specific methods in view handling all cases eg showinvalidEmail(), showinvalidPassword() etc. 在处理所有情况的视图中创建特定的方法,例如showinvalidEmail(),showinvalidPassword()等。

    • too many methods, difficult in complex cases. 方法太多,在复杂情况下很难。
  3. using enum for error type and passing to view view.showError(ErrorTypes.INVALID_EMAIL) -still confused about #enumsmatter :) 对错误类型使用枚举并传递给视图view.showError(ErrorTypes.INVALID_EMAIL)-仍然对#enumsmatter感到困惑:)

https://www.reddit.com/r/androiddev/comments/4v4urs/mvp_question_how_do_you_populate_your_textviews/ https://www.reddit.com/r/androiddev/comments/4v4urs/mvp_question_how_do_you_populate_your_textviews/

  1. Use a resource abstraction or wrapper class that provides the required string. 使用提供所需字符串的资源抽象或包装器类。
    • difficult when there are large number of strings to be used. 当要使用大量字符串时很难。

https://medium.com/@daptronic/android-mvp-the-curious-case-of-resources-ddca39c1fccd https://medium.com/@daptronic/android-mvp-the-curious-case-of-resources-ddca39c1fccd

  1. use library that provides api implementation for each string in strings.xml 使用库,为string.xml中的每个字符串提供api实现
    • still in beta stage 仍处于测试阶段

https://github.com/Comcast/resourceprovider https://github.com/Comcast/resourceprovider

Please suggest what is the best approach to attain this as to not violate the principles of mvp or clean architecture. 请提出实现此目标的最佳方法是什么,以免违反MVP或全新架构的原则。

As you already now which error you like to display when login failure so you just need to remove parameter from showError declaration and try to call that method from presenter without any parameter and view will be taking care of which message display when this showError function called as below : 既然您已经知道登录失败时要显示的错误,那么您只需要从showError声明中删除参数,然后尝试从演示者调用该方法而无需任何参数,当showError函数调用为as时,视图将负责显示哪个消息。下面:

View 视图

void showError(){
    Toast.makeText(this, getString(R.string.error), Toast.LENGTH_SHORT).show();
}

Presenter 主持人

mSignInView.showError();

And also define one more method to shown error from response as below : 并且还定义了另一种方法来从响应中显示错误,如下所示:

View 视图

void showError(String error){
    Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
}

Presenter 主持人

mSignInView.showError(error);

In my understandings MVP is not about taking away the android class from your business logic, but about separating the logic and UI part, and accessing an android class or resources from interactor is not a mistake. 以我的理解,MVP并不是要从业务逻辑中删除android类,而是要分离逻辑和UI部分,并从交互器访问android类或资源不是错误。

But if you want to separate completely, ie all android resources or classes from interactor then supply the type and read it from UI. 但是,如果您想完全分开,即将所有android资源或类与interactor分开,请提供类型并从UI读取它。

SignInViewActivity implements SignInView{
// additional code

    void showError(int errorType){
         switch(errorType){
             case ....:
         }
         //display message
    }
}

you can create an enumeration class like 您可以创建一个枚举类,例如

 enum class AuthError {
        INPUT_EMAIL_INVALID,
        INPUT_PASSWORD_INVALID,
        RESPONSE_EMAIL_DOES_NOT_EXIST
 }

Then you can pass it to view like this 然后您可以将其传递给这样的视图

AuthView.someError(AuthError.INPUT_EMAIL_INVALID)

You can check the type of the error by checking the type of the AuthError from there you can call R.string.error_message 您可以从那里检查AuthError的类型来检查错误的类型,然后可以调用R.string.error_message

This would remove the Presenter with Android Specific code. 这将删除带有Android特定代码的Presenter。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM