昨日、RecyclerViewのクリックイベントがどうしても取得できずハマってしまったのでメモしておきます。
RecyclerView onClickイベントの基本系
Layout
RecyclerViewの中のitemを以下のようなレイアウトにした場合、
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/cardView"> </android.support.v7.widget.CardView> </LinearLayout>
onClickイベント
基本は RecyclerView.AdapterのonCreateViewHolder()
の実装にonClickイベントを書くことになると思う。ネット上の情報もほぼこれ。
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layoute.card_view_layout, parent,false) val holder = ViewHolder(itemView) //itemViewにリスナーを設定 holder.itemView.setOnClickListener { //クリックされたViewHolderの位置が取得できる val position = holder.getAdapterPosition(); doAction(piosition) } return holder }
ただし、CardViewのクリック時に選択されたことを表現する為にandroid:clickable="true"
を定義した場合、上記で言うitemViewのonClickイベントが取得できなくなります。
<android.support.v7.widget.CardView android:clickable="true" android:foreground="?android:attr/selectableItemBackground" ...
CardView OnClickの定義
CardViewでリスナーの定義をするには単純に
override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(R.layoute.card_view_layout, parent,false) val holder = ViewHolder(itemView) //CardViewにリスナーを設定 holder.itemView.findViewById<CardView>(R.id.cardView).setOnClickListener { val position = holder.getAdapterPosition(); doAction(piosition) } return holder }
とすればよい。
蛇足
上記のdoActionはAdapter内にベターっと書かずにActivityやFragment側で記述するのがシャレオツみたい。
interfaceを定義してうけとればよい。
Adapter
class FooAdapter( var mListener:onCardViewItemClick ): RecyclerView.Adapter<ViewHolder>(){ interface onCardViewItemClick{ fun onClick(position: Int) } override fun onCreateViewHolder(parent: ViewGroup, p1: Int): ViewHolder { ...中略 holder.itemView.findViewById<CardView>(R.id.cardView).setOnClickListener { val position = holder.getAdapterPosition(); mListener.onClick(piosition) } return holder } }
Fragment側で実装を渡そう
class BarFragment : Fragment(), FooAdapter.onCardViewItemClick{ override fun fun onClick(position: Int){ //doAction } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { ...略 recyclerView.adapter = FooAdapter(tihs) } }
リンク
リンク