使用 MVP 控制 Android 中的可见性

Controlling Visibility in Android with MVP

我正在 Android Studio 中使用 MVP 设计模式构建一个计数器应用程序。当计数器的值为 0 时,我想隐藏我的重置按钮,那么我应该在哪里放置我的代码来控制它的可见性?我有以下 类:

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()
    }

}

在你的 ContractInterface 添加

fun showResetButton()
fun hideResetButton()

在您的演示器中实现它并调用 activity 中的函数。修改您在 MainActivity 中的函数以获得乐趣 showResetButton()hideResetButton() 而不是 setButtonVisibility.

if else 逻辑应尽可能在 Presenter 中。

通过在 View 界面中添加一个函数来解决它,该函数将计数器的值作为参数。

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()

}