简体   繁体   中英

How correctly apply MVP pattern in my sample

I decide to learn about MVP pattern and after look through some articles i want to try it with my current project.

I have choosen one activity and begin to think how i can decouple it according MVP rules. And eventually I don't know how to do it. It seems like a not complicated activity but I don't know

Could please someone adviced me with what I have to start?

Which methods have to be in presenter, witch view have to be left in this current activity and whitch methods have to be in interface?

Just advised me who i supposed to begin.

This is my class

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);
}
}

Thanks in advance!

The things to take into account are:

  • The view needs to be as dumb as possible. Think of it as an executor of the commands given by the presenter, and reporter to the presenter of all the stuff that happened on the UI. The interface should provide methods like "display this text", and / or calling presenter's methods like "the button was clicked".

  • the presenter is the one in command. It drives your view behaviour and reacts to the inputs coming from the view itself. Ideally, it should abstract from anything Android related, in this way you can test the behaviour inside vanilla tests.

Google has published a collection of samples to discuss and showcase different architectural tools and patterns for Android apps.

To begin, very usefull to you to understand how this one works . And adapt to your sample.

[...] This sample is the base for many of the variants. It showcases a simple implementation of the Model-View-Presenter pattern with no architectural frameworks. It uses manual dependency injection to provide a repository with local and remote data sources. Asynchronous tasks are handled with callbacks [...]

在此处输入图片说明

I highly recommend reading this article on medium: https://medium.com/@tinmegali/model-view-presenter-mvp-in-android-part-1-441bfd7998fe#.f4yiylrwa .

In essence, all things related to the android SDK should be put in your "view" (and occasionally your model), which will usually be a fragment or activity. Figuring out the difference between your model and presenter will be more up to you, however, you can think about your presenter as the thing that makes program logic decisions based on inputs to your application. Often, the mvp pattern is used in Android development to try to get around rotation and activity recreation issues so you may have luck using a static presenter for a small sample application.

Best of luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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