Everyday Growing Engineer 2023. 3. 10. 09:51

MVP 패턴 기본 내용 : https://growing-software-engineer.tistory.com/25

예제 코드 : 

1. Contract.interface

interface Contract {
    interface View {
        fun showProgress()
        fun hideProgress()
        fun setString(string: String?)
    }

    interface Model {
        interface OnFinishedListener {
            fun onFinished(string: String?)
        }
        fun getNextCourse(onFinishedListener: OnFinishedListener?)
        fun initCourse(onFinishedListener: OnFinishedListener?)
    }

    interface Presenter {
        fun initView()
        fun onButtonClick()
        fun onDestroy()
    }
}

2.MvpModel.class

import android.os.Handler
import android.os.Looper
import java.util.*

class MvpModel: Contract.Model  {

    private val arrayList =
        Arrays.asList(
            "DSA Self Paced: Master the basics of Data Structures and Algorithms to solve complex problems efficiently. ",
            "Placement 100: This course will guide you for placement with theory,lecture videos, weekly assignments " +
                    "contests and doubt assistance.",
            "Amazon SDE Test Series: Test your skill & give the final touch to your preparation before applying for " +
                    "product based against like Amazon, Microsoft, etc.",
            "Complete Interview Preparation: Cover all the important concepts and topics required for the interviews. " +
                    "Get placement ready before the interviews begin",
            "Low Level Design for SDE 1 Interview: Learn Object-oriented Analysis and Design to prepare for " +
                    "SDE 1 Interviews in top companies"
        )

    override fun getNextCourse(onFinishedListener: Contract.Model.OnFinishedListener?) {
        Handler(Looper.getMainLooper()).postDelayed({
             onFinishedListener!!.onFinished(getRandomString)
        }, 300)
    }

    override fun initCourse(onFinishedListener: Contract.Model.OnFinishedListener?) {
        onFinishedListener!!.onFinished(getRandomString)
    }

    private val getRandomString: String
        get() {
            val random = Random()
            val index = random.nextInt(arrayList.size)
            return arrayList[index]
        }
}

3.Presenter.class

class Presenter(private var mainView: Contract.View?, private val model: Contract.Model) : Contract.Presenter,
    Contract.Model.OnFinishedListener {

    override fun initView(){
        model.initCourse(this)
    }

    override fun onButtonClick() {
        if (mainView != null) {
            mainView!!.showProgress()
        }
        model.getNextCourse(this)
    }

    override fun onDestroy() {
        mainView = null
    }

    override fun onFinished(string: String?) {
        if (mainView != null) {
            mainView!!.setString(string)
            mainView!!.hideProgress()
        }
    }
    //buttonclick -> getNextCourse ->onFinished
}

4. fragment_mvp_pattern.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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=".fragments_code_examples.mvp_pattern.MvpPatternFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#168BC34A"
            tools:context=".MainActivity">

        <TextView
                android:id="@+id/textView3"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="MVP Architecture"
                android:textAlignment="center"
                android:textColor="@android:color/holo_green_dark"
                android:textSize="30sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.498"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.060000002"/>

        <TextView
                android:id="@+id/textView"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:padding="8dp"
                android:textAlignment="center"
                android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
                app:layout_constraintBottom_toTopOf="@+id/button"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView3"/>

        <Button
                android:id="@+id/button"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="다음 글"
                android:textColor="@android:color/background_light"
                android:textSize="20sp"
                android:textStyle="bold"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/textView" android:layout_marginLeft="100dp"
                android:layout_marginRight="100dp"/>

        <ProgressBar
                android:id="@+id/progressBar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

5. MvpPatternFragment.class

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import my.android_study.databinding.FragmentMvpPatternBinding

class MvpPatternFragment : Fragment(), Contract.View {

    private lateinit var binding: FragmentMvpPatternBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentMvpPatternBinding.inflate(inflater, container, false)
        val view = binding.root

        val presenter = Presenter(this, MvpModel())
        presenter.initView()
        binding.button.setOnClickListener { presenter.onButtonClick() }


        return view
    }

    override fun showProgress() {
        binding.progressBar.visibility = View.VISIBLE
        binding.textView.visibility = View.INVISIBLE
    }

    override fun hideProgress() {
        binding.progressBar.visibility = View.GONE
        binding.textView.visibility = View.VISIBLE
    }

    override fun setString(string: String?) {
        binding.textView.text = string
    }
}