MVP Architecture with Example in Android

I have already covered MVP's basic explanation in this blog
In this blog, we will practically take an example of a login screen in android and will try to cover up MVP in a very simple way.

As we can see in the above screen we have the Username and Password field and a Login button.
If the user enters the username and password and tries to log in we will show a success or error message in a text view below the button.
Here we will have 3 parts as MVP says
- Model part-> Contains logic
- View Part-> Contains UI part
- Presenter Part-> Responsible for communication between Model and View
Here is the project structure of our application

Let's Discuss 1 By 1 in Detail
The View part is responsible for getting user’s input and sending to Model
Code of MainActivity
class MainActivity : AppCompatActivity(), LoginResultListener {
//declaration of the views
private lateinit var etUserName: EditText
private lateinit var etPassword: EditText
private lateinit var btnLogin: Button
private lateinit var tvResult: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initUI()
}
private fun initUI() {
//Binding the xml with kotlin code
etUserName = findViewById(R.id.etUserName)
etPassword = findViewById(R.id.etPassword)
btnLogin = findViewById(R.id.btnLogin)
tvResult = findViewById(R.id.tvResult)
//btn click listener
btnLogin.setOnClickListener {
//Creating the object of presenter and passing reference of login result listener
var presenter = LoginModel(this)
// passing user name and password to login model by do login method
presenter.doLogin(etUserName.text.toString(), etPassword.text.toString())
}
}
override fun onSuccess(result: String) {
tvResult.text = result
}
override fun onFail(errorMessage: String) {
tvResult.text = errorMessage
}
}
LoginResultListener is an interface which is responsible for listening the result status we will send the result from model to view by using this interface.
interface LoginResultListener {
fun onSuccess(result: String)
fun onFail(errorMessage: String)
}
The view part is over till now
Pesenter part is responsible for presenting the data to model
The presenter has a doLogin method which will be implemented by Login Model and will have the logic for valid user login,In do login method we are sending the username and password entered by user.
@FunctionalInterface
interface LoginPresenter {
fun doLogin(userName: String, password: String)
}
Model Part is having the logic of valid user
In Login model we are passing the instace of LoginResultListener which will help us to send the data back to the UI again if user has entered correct username and passowrd we will send success else we will send the fail message.
class LoginModel(var loginResult: LoginResultListener) : LoginPresenter {
override fun doLogin(userName: String, password: String) {
if (userName == "Aalishan" && password == "12345") {
loginResult.onSuccess("Login Success Welcome $userName")
} else {
loginResult.onFail("Provided credentials are wrong")
}
}
}
We have completed all the coding part here and if you want to have source code you can download from here and play around.