androidandroid-studiokotlinmvpandroid-mvp

Controlling Visibility in Android with MVP


I’m building a counter app with MVP design pattern in Android Studio. I want to hide my reset button when the value of the counter is 0 so where should I put my code for controlling its visibility? I have the following classes:

MainActivity.kt

package com.example.mvpexample

import android.os.Bundle
import android.view.View
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.example.mvpexample.contract.ContractInterface
import com.example.mvpexample.databinding.ActivityMainBinding
import com.example.mvpexample.presenter.MainActivityPresenter

class MainActivity : AppCompatActivity(), ContractInterface.View {

    private lateinit var binding: ActivityMainBinding

    private var presenter: MainActivityPresenter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        presenter = MainActivityPresenter(this)

    }

    override fun initView() {

        binding.increment.setOnClickListener { presenter?.incrementValue() }
        binding.decrement.setOnClickListener { presenter?.decrementValue() }
        binding.reset.setOnClickListener { presenter?.resetValue() }

    }

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

    fun setButtonVisibility(isZero: Boolean, button: Button) {
        if (isZero) {
            button.visibility = View.GONE
        } else {
            button.visibility = View.VISIBLE
        }
    }
}

MainActivityPresenter.kt

package com.example.mvpexample.presenter

import com.example.mvpexample.contract.ContractInterface.*
import com.example.mvpexample.model.MainActivityModel

class MainActivityPresenter(_view: View) : Presenter {

    private var view: View = _view
    private var model: Model = MainActivityModel()

    init {
        view.initView()
    }

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

    override fun decrementValue() {
        model.decrementCounter()
        view.updateViewData()
    }

    override fun resetValue() {
        model.resetCounter()
        view.updateViewData()
    }

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

}

MainActivityModel.kt

package com.example.mvpexample.model

import com.example.mvpexample.contract.ContractInterface.Model

class MainActivityModel : Model {

    private var mCounter = 0

    override fun getCounter() = mCounter

    override fun decrementCounter() {
        if (mCounter == 0)
            return
        mCounter--
    }

    override fun incrementCounter() {
        mCounter++
    }

    override fun resetCounter() {
        mCounter = 0
    }

}

ContractInterface.kt

package com.example.mvpexample.contract

import android.widget.Button

interface ContractInterface {

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

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

    interface Model {
        fun getCounter(): Int
        fun decrementCounter()
        fun incrementCounter()
        fun resetCounter()
    }

}

Solution

  • Solved it by adding a function within View interface which carries the value of the counter as parameter.

    ContractInterface.kt

    package com.example.mvpexample.contract
    
    import android.widget.Button
    
    interface ContractInterface {
    
        interface View {
            fun initView()
            fun displayResetButton(countValue: Int)
            fun updateViewData()
        }
    
        interface Presenter {
            fun incrementValue()
            fun decrementValue()
            fun resetValue()
            fun getCounter(): String
        }
    
        interface Model {
            fun getCounter(): Int
            fun decrementCounter()
            fun incrementCounter()
            fun resetCounter()
        }
    
    }
    

    MainActivity.kt

    package com.example.mvpexample
    
    import android.os.Bundle
    import android.view.View
    import android.widget.Button
    import androidx.appcompat.app.AppCompatActivity
    import com.example.mvpexample.contract.ContractInterface
    import com.example.mvpexample.databinding.ActivityMainBinding
    import com.example.mvpexample.presenter.MainActivityPresenter
    
    class MainActivity : AppCompatActivity(), ContractInterface.View {
    
        private lateinit var binding: ActivityMainBinding
    
        private var presenter: MainActivityPresenter? = null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
            presenter = MainActivityPresenter(this)
    
        }
    
        override fun initView() {
    
            binding.increment.setOnClickListener { presenter?.incrementValue() }
            binding.decrement.setOnClickListener { presenter?.decrementValue() }
            binding.reset.setOnClickListener { presenter?.resetValue() }
    
        }
    
        override fun displayResetButton(countValue: Int) {
            if (countValue > 0) {
                binding.reset.visibility = View.VISIBLE
            } else {
                binding.reset.visibility = View.GONE
            }
        }
    
    
        override fun updateViewData() {
            binding.counter.text = presenter?.getCounter()
        }
    }
    

    MainActivityPresenter.kt

    package com.example.mvpexample.presenter
    
    import com.example.mvpexample.contract.ContractInterface.*
    import com.example.mvpexample.model.MainActivityModel
    
    class MainActivityPresenter(_view: View) : Presenter {
    
        private var view: View = _view
        private var model: Model = MainActivityModel()
    
        init {
            view.initView()
            view.displayResetButton(model.getCounter())
        }
    
        override fun incrementValue() {
            model.incrementCounter()
            view.displayResetButton(model.getCounter())
            view.updateViewData()
        }
    
        override fun decrementValue() {
            model.decrementCounter()
            view.displayResetButton(model.getCounter())
            view.updateViewData()
        }
    
        override fun resetValue() {
            model.resetCounter()
            view.displayResetButton(model.getCounter())
            view.updateViewData()
        }
    
        override fun getCounter() = model.getCounter().toString()
    
    }