はじめに
今回はMVP(アーキテクチャ)に沿って、recyclerviewとの連携を実装していきたいと思います。
実装内容
・追加ボタンを押した時にrecyclerviewにアイテム(✖︎マークのセル)を追加し表示する。
・✖︎マークのセルを押した際に押したセルを削除し、反映させる。
実装
[レイアウト]
①addButton
②recyclerView
[コード]
・準備
①BasePresenter,BaseViewを作成。
interface BasePresenter {
//起動処理のメソッド
fun start()
}
interface BaseView<T> {
var presenter: T
}
・Contract設定
①Contractを作成。
②View、Presenterのインターフェースを作成
③View、Presenterで使用するメソッドを作成。
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で作成したメソッドが色々出てくるので設定。
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のメソッドを呼び出す。
//②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のメソッドを呼び出す。
//①戻り値に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)との連携