LoginSignup
0
0

【kotlin】超簡単なMVPを実装してみた、⑤recyclerviewとの連携

Last updated at Posted at 2022-02-05

はじめに

今回はMVP(アーキテクチャ)に沿って、recyclerviewとの連携を実装していきたいと思います。

実装内容

・追加ボタンを押した時にrecyclerviewにアイテム(✖︎マークのセル)を追加し表示する。
・✖︎マークのセルを押した際に押したセルを削除し、反映させる。

Screenshot_1644046349.png

実装

[レイアウト]
①addButton
②recyclerView
Screenshot_1644046349.png

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

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

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

MainContract
interface MainContract {

    interface View: BaseView<Presenter> {
        //③RecyclerViewを初期化するメソッド
        fun setRecyclerView (rvList: ArrayList<String>)
        //③RecyclerViewを更新するメソッド
        fun updateRecyclerView (rvList: ArrayList<String>)
        //③✖︎ボタンクリックされた際にview側に渡すメソッド
        fun onClickCellDeleteButton (position: Int)
    }

    interface Presenter: BasePresenter {
        //③Activity側のaddButoonをクリックされた際に使用するメソッド
        fun onClickAddButton ()
        //③RecyclerViewの✖︎Butoonをクリックされた際に使用するメソッド
        fun onClickCellDeleteButton (position: Int)
    }
}

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

MainPresenter
class MainPresenter(private val view: MainContract.View): MainContract.Presenter {
    var rvList = ArrayList<String>()

    //④view.presenter = thisに設定。
    init {
        view.presenter = this
    }

    //⑤追加ボタンが押された時の処理
    override fun onClickAddButton() {
        rvList.add("✖️")
        view.updateRecyclerView(rvList)
    }

    //⑤✖︎ボタンが押された時の処理
    override fun onClickCellDeleteButton(position: Int) {
        rvList.removeAt(position)
        view.updateRecyclerView(rvList)

    }

    //⑤起動時の処理
    override fun start() {
        view.setRecyclerView(rvList)
    }
}

・Adapter設定
①Adapter作成。
②MainContract.Viewを引数に設定。
③MainContract.Viewのメソッドを呼び出す。

RvAdapter
//②MainContract.Viewを引数に設定。
class RvAdapter(private val litner: MainContract.View,
                private val List: ArrayList<String>,
                private val context: Context): RecyclerView.Adapter<RvAdapter.ViewHolder>(){

    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val cellDeleteButton: TextView

        init{
            cellDeleteButton  = view.findViewById<TextView>(R.id.cellDeleteButton)
        }

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RvAdapter.ViewHolder {
        val view = LayoutInflater.from(context).inflate(R.layout.cell, parent, false)
        view.layoutParams.height= 150
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: RvAdapter.ViewHolder, position: Int) {
        holder.cellDeleteButton.setOnClickListener {
            //③view側に渡すpositionを渡すメソッド
            litner.onClickCellDeleteButton(position)
        }
    }

    override fun getItemCount(): Int {
        return List.size
    }
}

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

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

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

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

        addButton = findViewById(R.id.addButton)
        recyclerView = findViewById(R.id.recyclerView)
        initPresenter()
        presenter.start()
        addButton.setOnClickListener {
            presenter.onClickAddButton()
        }
    }

    //③RecyclerViewをセットする
    override fun setRecyclerView(rvList: ArrayList<String>) {
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.setPadding(10,20,10,0)
        val dividerItemDecoration = DividerItemDecoration(this, LinearLayoutManager(this).getOrientation())
        getDrawable(R.drawable.divider)?.let { dividerItemDecoration.setDrawable(it) }
        recyclerView.addItemDecoration(dividerItemDecoration)
        var adapter = RvAdapter(this, rvList, applicationContext)
        recyclerView.adapter = adapter
    }

    //③RecyclerViewを更新する
    override fun updateRecyclerView(rvList: ArrayList<String>) {
        var adapter = RvAdapter(this, rvList, applicationContext)
        recyclerView.adapter = adapter
    }
    //③✖︎ボタンが押された時呼び出される
    override fun onClickCellDeleteButton(position: Int) {
        presenter.onClickCellDeleteButton(position)
    }

    fun initPresenter() {
        if (::presenter.isInitialized) {
            return
        }
        presenter = MainPresenter(this)
    }
}

以上、recyclerviewとの連携との連携でした。
AdpterとPresenterで直接やり取りするではなくて、
Viewを経由してpresenterに送るイメージです。

関連記事

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

参考資料

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

0
0
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
0