0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【kotlin】超簡単なMVPを実装してみた、④異なるレイアウト(Fragment)との連携

Last updated at Posted at 2022-01-23

はじめに

今回はMVP(アーキテクチャ)に沿って、異なるレイアウト(Fragment)との連携を実装していきたいと思います。

実装内容

・Activity(親View)の下半分にFragment(子View)を重ねる。
・ACTIVITYボタン(紫文字)が押された際に双方ViewのTextViewに1を足し、表示する。
・FRAGEMENTボタン(赤文字)が押された際に双方ViewのTextViewに10を足し、表示する。
Screenshot_1642842015.png

実装

[レイアウト]
Activity(親)側
①activityButton
②activityTextView
Fragment(子)側
③fragmentButton
④fragmentTextView
Screenshot_1642842015.png

[コード]
・準備
①BasePresenter,BaseViewを作成。

BasePresenter
interface BasePresenter {
     //起動処理のメソッド
    fun start()
}
BaseView
interface BaseView<T> {
    var presenter: T
}

・Contract設定
①Contractを作成。
②Activity、Fragment、Presenterのインターフェースを作成
③ActivityとFragmentとpresenterで使用するメソッドを作成。

MainContract
interface MainContract {

    interface Activity: BaseView<Presenter> {
        //③Activity側のTextViewをテキストを表示するメソッド
        fun showActivityTextView (text: String)
    }

    interface Fragment: BaseView<Presenter> {
        //③Fragment側のTextViewをテキストを表示するメソッド
        fun showFragmentTextView (text: String)
    }

    interface Presenter: BasePresenter {
        //③Activity側のButoonをクリックされた際に使用するメソッド
        fun onClickActivityButton ()
        //③Fragment側のButoonをクリックされた際に使用するメソッド
        fun onClickFragmentButton ()
    }
}

・Presenter設定
①Presenter作成。
②Contract.Activityを引数に追加。
③Contract.Fragmentを引数に追加。
④Contract.presenter(MainContract.Presenter)を戻り値に追加。
⑤activity.presenter = thisに設定。
⑥fragment.presenter = thisに設定。
⑦Contractで作成したメソッドが色々出てくるので設定。

MainPresenter
class MainPresenter(private val activity: MainContract.Activity,
                    private val fragment: MainContract.Fragment): MainContract.Presenter {

    //数字をカウントする変数
    var cnt = 0

    //初期化
    init {
        //⑤activity.presenter = thisに設定。
        activity.presenter = this
        //⑥fragment.presenter = thisに設定。
        fragment.presenter = this
    }

    //⑦Activity側のボタンが押された時の処理
    override fun onClickActivityButton() {
        cnt += 1
        activity.showActivityTextView(cnt.toString())
        fragment.showFragmentTextView(cnt.toString())
    }
    //⑦Fragment側のボタンが押された時の処理
    override fun onClickFragmentButton() {
        cnt += 10
        activity.showActivityTextView(cnt.toString())
        fragment.showFragmentTextView(cnt.toString())
    }

    override fun start() {
    }
}

・Fragment(子View)設定
①Fragment作成。
②Fragmentの戻り値にContract.Fragmentを追加。
③fragmentを親Viewに渡す。
④overrideしたContract.presenter(MainContract.Presenter)を追加。
⑤Contractで作成したメソッドが色々出てくるので設定。
⑥presenterのメソッドを呼び出す

MainFragment
//②Fragmentの戻り値にContract.Fragmentを追加。
class MainFragment : Fragment(), MainContract.Fragment {

    ////④overrideしたContract.presenter(MainContract.Presenter)を追加。
    override lateinit var presenter: MainContract.Presenter

    lateinit var fragmentTextView :TextView
    lateinit var fragmentButton :Button

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_main, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        fragmentTextView = view.findViewById(R.id.fragmentTextView)
        fragmentButton = view.findViewById(R.id.fragmentButton)
        //③fragmentを親Viewに渡す。
        activity?.let {
            if (it is MainActivity) {
                it.initPresenter(this)
            }
        }


        fragmentButton.setOnClickListener {
            //⑥presenter.onClickFragmentButtonを呼び出す。
            presenter.onClickFragmentButton()
        }
    }

    //⑤FragmentTextViewに文字を表示させる
    override fun showFragmentTextView(text: String) {
        fragmentTextView.text = text
    }
}

・Activity(親View)設定
①Activityの戻り値にContract.Activityを追加。
②overrideしたContract.presenter(MainContract.Presenter)を追加。
③Contractで作成したメソッドが色々出てくるので設定。
④presenterのメソッドを呼び出す。

MainActivity
//①戻り値にContract.Activityを追加。
class MainActivity : AppCompatActivity(), MainContract.Activity {

    //②overrideしたContract.presenter(MainContract.Presenter)を追加。
    override lateinit var presenter: MainContract.Presenter

    //空の子Viewを用意する。
    var mainFragment : MainFragment? = null

    lateinit var activityTextView : TextView
    lateinit var activityButton : Button

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

        //③Fragment設定(引数に自分を入れる)。
        val transition = supportFragmentManager.beginTransaction()
        transition.add(R.id.fragmentLayout, MainFragment())
        transition.commit()


        activityTextView = findViewById(R.id.activityTextView)
        activityButton = findViewById(R.id.activityButton)

        activityButton.setOnClickListener {
            //⑤presenter.onClickActivityButtonを呼び出す。
            presenter.onClickActivityButton()
        }
    }
    //③ActivityTextViewに文字を表示させる
    override fun showActivityTextView(text: String) {
        activityTextView.text = text
    }

    fun initPresenter(main : MainFragment? = null) {
        if (::presenter.isInitialized) {
            return
        }
        main?.let {
            this.mainFragment = it
        }
        //子Viewがnulじゃない場合、Presenterを起動する。
        if (mainFragment != null) {
            presenter = MainPresenter(this, mainFragment!!)
        }
    }
}

以上、異なるレイアウト(Fragment)との連携でした。
ロジカルな処理がpresenterに集まって、いい感じになったと思います。

Viewが一つだけ相違点をまとめると以下となっております。
・Viewの数だけContractでインターフェースを作成する。
・親Viewに子Viewを渡し、Presenterの初期化を行う。

関連記事

【kotlin】超簡単なMVPを実装してみた、①Presenterの実装
【kotlin】超簡単なMVPを実装してみた、②LocalRepository設定(ローカルデータに保存、読み込み)
【kotlin】超簡単なMVPを実装してみた、③RemoteRepository設定(APIのやり取り)
【kotlin】超簡単なMVPを実装してみた、⑤recyclerviewとの連携

参考資料

Android アプリ設計パターン入門
テストが書けない人のAndroid MVP
todo-mvp

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?