Ví dụ triển khai mô hình MVP trong android

Bài viết về MVP chắc các bạn cũng đã xem rất nhiều trên mạng rồi, tuy nhiên trước khi bắt đầu bài viết mình điểm lại một số nội dung chính về MVP như sau:

Mô hình MVP chia project thành 3 lớp M.V.P:

  • M – Model: lớp này dùng để xử lý dữ liệu(tao dữ liệu, lấy dữ liêu…), chịu trách nhiệm lấy dữ liệu từ database hoặc network. Dữ liệu được đưa vào model rồi đẩy sang Presenter thông qua các hàm callback.
  • V- View: lớp này dùng để đưa dữ liệu vào view, nhận dữ liệu từ lớp presenter
  • P – Presenter: lớp này sẽ là lớp xử lý các bussiness logic, P là lớp trung gian có thể giao tiếp được với hai lớp Model View ( M – V ko  giao tiếp trực tiếp với nhau).
    Khi lớp View nhận một event từ người dùng sự kiện sẽ gửi xuống lớp Presenter, lớp Presenter lấy sẽ liệu từ lớp Model đẩy lên lớp View.

Ví dụ: Xây dựng mô hình MVP hiển thị 1 dữ liệu từ lớp Model bất kỳ ra ListView.

B1: Tạo 3 package lần lượt là model, view, presenter.

  • Đầu tiên định nghĩa lớp MainView hiển thị dữ liệu, lớp này được implement tại MainActivity.
/**
 * - Lớp View định nghĩa các hàm hiển thị dữ liệu
 */

public interface MainView {
    void displayMain(List<Demo> listDemo);
}
  • Tạo 1 entity đơn giản tên Demo:
public class Demo {
    private String message;

    public Demo(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "Demo{" +
                "message='" + message + '\'' +
                '}';
    }
}
  • Tạo một interface: LoadDemoListener.java làm callback cho lớp Model
public interface LoadDemoListener {
    void onLoadDemoSuccess(List<Demo> listDemo);
    void onLoadDemoFailure(String message);
}
  • Tiếp theo tạo một UserInterator.java lớp này là lớp xử lý, dữ liệu đẩy vào callback để đưa qua lớp presenter
/*
*- Lớp M: xử lý dữ liệu -> Trả dữ liệu về P thông qua callback
* */

public class UserInterator {
    private LoadDemoListener listener;

    public UserInterator(LoadDemoListener listener) {
        this.listener = listener;
    }

    //Xử lý tạo dữ liệu
    public void createListData(){
        List<Demo> listDemo = new ArrayList<>();
        for (int i = 0 ; i < 10; i++){
            Demo demo = new Demo("I'm Developer!");
            listDemo.add(demo);
        }
        listener.onLoadDemoSuccess(listDemo);
    }
}
  • Tiếp theo tạo lớp MainPresenter.java lớp này dùng để xử lý các logic, nhận dữ liệu từ lớp model thông qua các hàm callback, nhiệm vụ đẩy lên View hướng dẫn cách View hiển thị:
public class MainPresenter implements LoadDemoListener {
    private UserInterator mainInterator;
    private MainView mainView;
    public MainPresenter(MainView mainView) {
        this.mainView = mainView;
        mainInterator = new UserInterator(this);
    }

    public void loadData() {
        mainInterator.createListData();
    }

    @Override
    public void onLoadDemoSuccess(List<Demo> listDemo) {
        mainView.displayMain(listDemo);
    }

    @Override
    public void onLoadDemoFailure(String message) {
        //Làm gì đó nếu xảy ra lỗi.
    }
}
  • Cuối cùng tại MainActivity.java khởi tạo presenter, tạo sự kiện load dữ liệu, cấu hình hiển thị cho listview.
public class MainActivity extends AppCompatActivity implements MainView {
    //Presenter
    private MainPresenter mainPresenter;
    private ListView listView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initPresenter();
        Button btnLoad = (Button) findViewById(R.id.btn_load_data);
        listView = (ListView) findViewById(R.id.list_view);
        btnLoad.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               mainPresenter.loadData();
            }
        });
    }

    private void initPresenter() {
        mainPresenter = new MainPresenter(this);
    }

    @Override
    public void displayMain(List<Demo> listDemo) {
        listView.setAdapter(new ArrayAdapter<Demo>(this,android.R.layout.simple_list_item_1,listDemo));
    }
}
  • Layout cho main activity như sau:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.lynkmieu.mvpsamplev1.view.MainActivity">

    <Button
        android:id="@+id/btn_load_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Data MVP" />
    <ListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/list_view"/>

</LinearLayout>

Source code Github.

Tìm hiểu thêm tại đây: Android Architecture!

Nguyễn Linh

Chia sẻ để cùng tiến bộ...

Bình luận đã bị khoá.