Android Kotlin MVP – แอพ Counter

สร้างแอพ Counter แบบ MVP (Model View Presenter) โดยทุกครั่งที่กดปุ่ม ตัวเลขก็จะเพิ่มขึ้นเรื่อยๆ

MVP – Model View Presenter

  • View: The views are responsible for deciding how the data is to be displayed to the user. Normally the view is the Activity or Fragment
  • Presenter: This is the brain of the app. All the business logic is kept here. It is responsible for keeping the view and model away from each other. View and Model can only talk through the Presenter.
  • Model: This is the data centre of the app. All the data is kept here and when the model is changed, instead of updating the view directly, the presenter is notified to update the views accordingly.

สร้างโปรเจ็กส์ชื่อ Counter โดยจะมีไฟล์ต่างๆดังนี้

1.สร้าง Interface ชื่อ ContractInterface

ContractInterface.kt

package com.phaisarn.counter.contract

interface ContractInterface {
    interface Model {
        fun getCounter(): Int
        fun incrementCounter()
    }

    interface View {
        fun initView()
        fun updateViewData()
    }

    interface Presenter {
        fun getCounter(): String
        fun incrementValue()
    }
}

2.สร้าง Class ชื่อ MainActivityModel

MainActivityModel.kt

package com.phaisarn.counter.model

import com.phaisarn.counter.contract.ContractInterface.*

class MainActivityModel : Model {
    private var mCounter = 0

    override fun getCounter() = mCounter

    override fun incrementCounter() {
        mCounter++
    }
}

3.สร้าง Class ชื่อ MainActivityPresenter

MainActivityPresenter.kt

package com.phaisarn.counter.presenter

import com.phaisarn.counter.contract.ContractInterface.*
import com.phaisarn.counter.model.MainActivityModel

class MainActivityPresenter(_view: View) : Presenter {
    private var view: View = _view
    private var model: Model = MainActivityModel()

    init {
        view.initView()
    }

    override fun getCounter() = model.getCounter().toString()

    override fun incrementValue() {
        model.incrementCounter()
        view.updateViewData()
    }
}

4.สร้าง Class ชื่อ MainActivity

ลบคลาส MainActivity เดิมและสร้าง Class ชื่อ MainActivity ขึ้นมาใหม่ (หรือจะ Move แล้วเหลี่ยนชื่อ package เอาก็ได้)

MainActivity.kt

package com.phaisarn.counter.view

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.phaisarn.counter.R
import com.phaisarn.counter.contract.ContractInterface.*
import com.phaisarn.counter.presenter.MainActivityPresenter
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity(), View {
    private var presenter: MainActivityPresenter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        presenter = MainActivityPresenter(this)
    }

    override fun initView() {
        counterTextView.text = presenter?.getCounter()
        clickButton.setOnClickListener { presenter?.incrementValue() }
    }

    override fun updateViewData() {
        counterTextView.text = presenter?.getCounter()
    }
}

5.แก้ไขไฟล์ activity_main.xml

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.MainActivity">

    <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent">
        <TextView
                android:id="@+id/counterTextView"
                android:layout_width="match_parent"
                android:textSize="72sp"
                android:textAlignment="center"
                android:layout_height="wrap_content"/>

        <Button
                android:id="@+id/clickButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="36dp"
                android:layout_gravity="center"
                android:text="Counter"/>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

6.แก้ไขไฟล์ AndroidManifest.xml

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:dist="http://schemas.android.com/apk/distribution"
          package="com.phaisarn.counter">

    <dist:module dist:instant="true"/>

    <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".view.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>