2016-11-07 26 views
0

我决定了解MVP模式,并查看一些文章后,我想用我当前的项目尝试。如何在我的示例中正确应用MVP模式

我选择了一项活动,并开始思考如何根据MVP规则将其解耦。最终我不知道该怎么做。这似乎是一个不复杂的活动,但我不知道

可以请某人告诉我,我必须开始?

哪些方法必须在演示者中,女巫视图必须留在当前活动中,而且方法必须在界面中?

刚刚劝我,我该开始谁。

这是我的课

public final class ActivityUserDataScreen extends AppCompatActivity implements InterfaceActivityUserDataScreen{ 

private static String gender; 
private static int inputHeight; 
private static int inputWeight; 
private TextInputLayout tilUserName; 
private int backPressedQ = 0; 
private String avatarName; 

private static final String MEN = "men"; 
private static final String WOMEN = "men"; 

private Context context; 
private PresenterActivityUserDataScreen presenter; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Fabric.with(this, new Crashlytics()); 
    setContentView(R.layout.activity_user_data_screen); 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
    setSupportActionBar((Toolbar) findViewById(R.id.tool_bar)); 

    context = getApplicationContext(); 
    initNumberPicker(); 
    initVar(); 
    presenter = new PresenterActivityUserDataScreen(this); 
} 

private void initNumberPicker() { 
    NumberPicker pickerHeight = (NumberPicker) findViewById(R.id.pickerHeight); 
    UtilClass.setDividerColor(pickerHeight, UtilClass.getMyColor(context, R.color.ntz_color_yellow)); 
    pickerHeight.setOnValueChangedListener(changeListener); 
    pickerHeight.setMaxValue(220); 
    pickerHeight.setMinValue(130); 
    pickerHeight.setValue(States.HEIGHT_DEFAULT); 

    NumberPicker pickerWeight = (NumberPicker) findViewById(R.id.pickerWeight); 
    UtilClass.setDividerColor(pickerWeight, UtilClass.getMyColor(context, R.color.ntz_color_yellow)); 
    pickerWeight.setOnValueChangedListener(changeListener); 
    pickerWeight.setMaxValue(120); 
    pickerWeight.setMinValue(35); 
    pickerWeight.setValue(States.WEIGHT_DEFAULT); 
} 

private void initVar() { 
    tilUserName = (TextInputLayout) findViewById(R.id.tilUserName); 

    SwitchButton switchButton = (SwitchButton) findViewById(R.id.sb_custom); 
    switchButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if (isChecked){ 
       gender = WOMEN; 
      }else { 
       gender = MEN; 
      } 
     } 
    }); 

    EditText etAvatarName = (EditText) findViewById(R.id.etAvatarName); 
    etAvatarName.setText(getResources().getString(R.string.avatar)); 
} 

private NumberPicker.OnValueChangeListener changeListener = new NumberPicker.OnValueChangeListener() { 
    @Override 
    public void onValueChange(NumberPicker picker, int oldVal, int newVal) { 
     switch (picker.getId()) { 
      case R.id.pickerHeight: 
       inputHeight = newVal; 
       break; 
      case R.id.pickerWeight: 
       inputWeight = newVal; 
       break; 
     } 
    } 
}; 

@Override 
public final void onBackPressed() { 
    UtilClass.processClick(context); 

    if (backPressedQ == 1) { 
     backPressedQ = 0; 
     super.onBackPressed(); 
     overridePendingTransition(R.anim.open_main, R.anim.close_next); 

    } else { 
     backPressedQ++; 
     Toast.makeText(this, "Press again to exit", Toast.LENGTH_SHORT).show(); 
    } 

    //Обнуление счётчика через 5 секунд 
    final Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      backPressedQ = 0; 
     } 
    }, 5000); 
} 

public final void goNext(View view) { 
    UtilClass.processClick(context); 
    EditText editText = tilUserName.getEditText(); 
    Editable editable = null; 
    if (editText != null) { 
     editable = editText.getText(); 
    } 
    if (editable != null) { 
     avatarName = editable.toString(); 
    } 
    if (!isValidAvatarName()) return; 

    saveUserData(); 
    MetadataSaver saver = new MetadataSaver(context); 
    saver.saveFirstUserInfo(); 
    saver.saveDeviceInfo(); 
    PreferencesHelper.savePref(context, States.STILL_NOT_FINISH, true); 
    UtilClass.goToNextActivity(ActivityUserDataScreen.this, ActivityVideo.class); 
} 

private void saveUserData(){ 
    saveAvatarGender(); 
    saveAvatarHeight(); 
    saveAvatarWeight(); 
    saveAvatarName(); 
} 

private void saveAvatarGender(){ 
    if (gender == null){ 
     gender = MEN; 
    } 
    PreferencesHelper.savePref(context, States.AVATAR_GENDER, gender); 
} 

private boolean isValidAvatarName() { 
    if (UtilClass.isTextEmpty(avatarName)) { 
     tilUserName.setErrorEnabled(true); 
     tilUserName.setError(getResources().getString(R.string.fill_your_avatar_name)); 
     return false; 
    } 

    if (avatarName.contains(" ")) { 
     avatarName = avatarName.replace(" ", ""); 
    } 

    if (!UtilClass.isLatinAlphabet(avatarName)) { 
     tilUserName.setErrorEnabled(true); 
     tilUserName.setError(getResources().getString(R.string.avatar_name_in_english)); 
     return false; 
    } 

    if (!UtilClass.isNameFree(context, avatarName)) { 
     tilUserName.setErrorEnabled(true); 
     tilUserName.setError(getResources().getString(R.string.avatar_name_already_in_use)); 
     return false; 
    } 

    return true; 
} 

private void saveAvatarHeight() { 
    int result; 
    if (inputHeight == 0) { 
     result = States.HEIGHT_DEFAULT; 
    } else { 
     result = inputHeight; 
    } 

    PreferencesHelper.savePref(context, States.AVATAR_HEIGHT, result); 
} 

private void saveAvatarWeight() { 
    int result; 
    if (inputWeight == 0) { 
     result = States.WEIGHT_DEFAULT; 
    } else { 
     result = inputWeight; 
    } 
    PreferencesHelper.savePref(context, States.AVATAR_WEIGHT, result); 
} 

private void saveAvatarName() { 
    PreferencesHelper.savePref(context, States.AVATAR_NAME, avatarName); 
} 

public final void switchManWoman(View view) { 
    UtilClass.processClick(context); 
} 
} 

提前感谢!

+0

引入MVP的真正原因是为了提高可测性。此链接将帮助您正确理解MVP: https://codelabs.developers.google.com/codelabs/android-testing/ –

+0

使用此示例存储库,您可以了解有关MVP与匕首混合的更多信息:http:// github。 com/mmirhoseini/marvel –

回答

1

要考虑的事情是:

  • 的需要,以尽可能哑巴。把它看作是主持人给出的命令的执行者,而记者则是发布在UI上发生的所有事情的主持人。界面应该提供诸如“显示此文本”之类的方法,和/或调用演示者的方法,如“按钮被点击”。

  • 主讲人是指挥官。它驱动你的视图行为并对来自视图本身的输入作出反应。理想情况下,它应该从Android相关的任何东西中抽象出来,这样就可以测试香草测试中的行为。

+0

对不起,我忘了附上我目前的课程。添加到问题 –

+0

请教我请在哪里我应该初始化var?例如我有进度条,至少我需要找到它'findViewById()'而不是'setProgress(0)'和'setMax(100)'我应该怎么做?主持人还是看法?因为正如我理解初始化我应该做的视图,但调用具有集意义的方法我应该从主持人...另外我需要'findViewById()'做视图,但设置初始值'setProgress(0)'和'setMax(100) “我应该从主持人,是吗? –

1

Google已经发布a collection of samples来讨论和展示Android应用的不同架构工具和模式。

首先,非常有用地了解how this one works。并适应你的样本。

[...]此示例是许多变体的基础。它展示了Model-View-Presenter模式的简单实现,没有架构框架。它使用手动依赖注入来为存储库提供本地和远程数据源。异步任务与回调处理[...]

enter image description here

+0

对不起,我忘了附上我目前的课程。加入问题 –

+0

请教我请在哪里我应该初始化var?例如我有进度条,至少我需要找到它'findViewById()'而不是'setProgress(0)'和'setMax(100)'我应该怎么做?主持人还是看法?因为正如我理解初始化我应该做的视图,但调用具有集意义的方法我应该从主持人...另外我需要'findViewById()'做视图,但设置初始值'setProgress(0)'和'setMax(100) “我应该从主持人,是吗? –

0

我强烈建议你阅读这篇文章的介质:https://medium.com/@tinmegali/model-view-presenter-mvp-in-android-part-1-441bfd7998fe#.f4yiylrwa

从本质上讲,所有与android SDK相关的东西都应该放在你的“视图”(偶尔是你的模型)中,这通常是一个片段或活动。弄清楚你的模型和演示者之间的区别将取决于你,然而,你可以把你的演示者看作是根据你的应用程序的输入做出程序逻辑决定的东西。通常,Android开发中会使用mvp模式来尝试解决旋转和活动重新消息问题,因此您可能使用静态演示程序为小样本应用程序运气。

祝你好运!

+0

抱歉,我忘了附上我的课程。加入问题 –

+0

请教我请在哪里我应该初始化var?例如我有进度条,至少我需要找到它'findViewById()'而不是'setProgress(0)'和'setMax(100)'我应该怎么做?主持人还是看法?因为正如我理解初始化我应该做的视图,但调用具有集意义的方法我应该从主持人...另外我需要'findViewById()'做视图,但设置初始值'setProgress(0)'和'setMax(100) “我应该从主持人,是吗? –