Please enable JavaScript to view the comments powered by Disqus.

Apply MVP Pattern for Android

A - What is MVP?

MVP pattern stands for Model - View - Presenter.
MVP is a derivative from famous MVC guy. It allows separate the presentation layer from the business logic.

-   Model: handle persisting and retrieving data, along with any business logic that the data must adhere to

-   View: gather user input and update the display

-   Presenter: the "middle-man" handles the communication between Model and View

Separating user interface from logic in Android is not easy, but the MVP pattern makes a little easier to prevent our activities turn into very coupled classes consisting on hundreds or even thousands of lines.

That will make our Android application more testable, extendable and maintainable.

B - Demo apply MVP Pattern for Android

In this part, we will create a small and simple demo about applying MVP pattern for Android application.

This demo app allows user to add new product and load all the products.

Firstly, we need to create the layout:

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <EditText
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:id="@+id/et_product"
        android:hint="Product Name"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Add"
        android:id="@+id/btn_add"
        android:layout_below="@+id/et_product"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Load"
        android:id="@+id/btn_load"
        android:layout_below="@+id/btn_add"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/tv_products"
        android:layout_below="@+id/btn_load"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</RelativeLayout>

Then, create an Interface for the View:

IProductsView.java

public interface IProductsView {
    public void showProducts(String products);
    public void clearInputFields();
}

Lat the MainActivity implements the view interface above:

MainActivity.java

public class MainActivity extends ActionBarActivity implements IProductsView, View.OnClickListener {
    EditText mEtProduct;
    TextView mtvProducts;
    Button mBtnAdd;
    Button mBtnLoad;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEtProduct = (EditText)findViewById(R.id.et_product);
        mtvProducts = (TextView)findViewById(R.id.tv_products);
        mBtnAdd = (Button)findViewById(R.id.btn_add);
        mBtnLoad = (Button)findViewById(R.id.btn_load);
        mBtnAdd.setOnClickListener(this);
        mBtnLoad.setOnClickListener(this);
    }

    @Override
    public void showProducts(String products) {
        mtvProducts.setText(products);
    }

    @Override
    public void clearInputFields() {
        mEtProduct.setText("");
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_add: break;
            case R.id.btn_load: break;
        }
    }
}

Next, we move to Model part, create Product class:

Product.java

public class Product {
    private String mName;

    public Product(String name){
        mName = name;
    }

    public String getmName() {
        return mName;
    }
}

Now, we must create the Presenter class that contains the Model, View instances and some method to handle business logic:

ProductsPresenter.java

public class ProductsPresenter {
    IProductsView mView;
    List<Product> products;

    public ProductsPresenter(IProductsView view){
        mView = view;
        products = new ArrayList<Product>();
        products.add(new Product("Nikon D3200"));
    }

    public void addProduct(String product){
        products.add(new Product(product));
        mView.clearInputFields();
    }

    public void loadProducts(){
        String result = "";
        for(Product product : products){
            result += product.getmName() + "\n";
        }
        mView.showProducts(result);
    }
}

Now, get back to MainActivity and add the Presenter into it:

MainActivity.java

ProductsPresenter mProductsPresenter;
...

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    mProductsPresenter = new ProductsPresenter(this);
}

@Override
public void onClick(View v) {
    switch (v.getId()){
        case R.id.btn_add: mProductsPresenter.addProduct(mEtProduct.getText().toString()); break;
        case R.id.btn_load: mProductsPresenter.loadProducts(); break;
    }
}

Finally, run the demo and enjoy the result!

android-mvp-demo

C - Source code of Demo apply MVP Pattern for Android

https://drive.google.com/file/d/0Bw3dwdSezn6fd3JlNE8zeXlERE0/view?usp=sharing

http://www.mediafire.com/download/o8kcmnkicaxp6v5/DemoAndroidMVP.zip