Groupieでclickイベントを実装する
Groupieでのレンダリングは前に実装したんですが, Groupieでレンダリングしたリストに対してClickListenerをつけていきたいと思います. github:
interfaceとAdapterを用意する
クリック時の振る舞いはinterfaceとしてAdapterに渡してあげます. adapterは受け取ったinterfaceをListのそれぞれのItemに更に渡してあげる感じです.
用意するinterfaceはこんな感じです. 今回はMainActivityの中に作りました
interface MainListItemClickListener { fun onItemClick( itemId: String ) }
adapterはGroupAdapterを継承します. この時, GroupieでレンダリングするItemにlistenerを渡してあげます
class ListAdapter(private val listener: MainActivity.MainListItemClickListener) : GroupAdapter<GroupieViewHolder>() { fun updateList(list: List<MainActivity.Item>) { update(list.map { TopListItem( text = it.text, itemId = it.itemId, listener = listener ) }) } }
TopListItemはこんな感じです. itemIdは, クリックしたときにどのitemがクリックされたかを判別するために用意してます. IntでもStringでも何でもOKです.
class TopListItem( private val text: String, private val itemId: String, private val listener: MainActivity.MainListItemClickListener ) : BindableItem<ItemTopListBinding>() { override fun getLayout() = R.layout.item_top_list override fun bind(viewBinding: ItemTopListBinding, position: Int) { viewBinding.button.text = text viewBinding.button.setOnClickListener { listener.onItemClick( itemId = itemId ) } } override fun initializeViewBinding(view: View): ItemTopListBinding { return ItemTopListBinding.bind(view) } }
intefaceの中身を実装
onCreate関数の中でadapterを生成します. このときにinterfaceの中身を実装します. 無名クラスを使いました.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_main) val adapter = ListAdapter(object : MainListItemClickListener { override fun onItemClick(itemId: String) { itemClickHandler(itemId) } }) binding.recyclerView.adapter = adapter } private fun itemClickHandler(itemId: String) { when (itemId) { VIEW_A -> { val intent = Intent(this, ViewAActivity::class.java) startActivity(intent) } VIEW_B -> { val intent = Intent(this, ViewBActivity::class.java) startActivity(intent) } } }
最終的にはこんな感じで動作します.