Как добавить прослушиватель кликов для ItemDecoration в RecyclerView Android?
Я пытался добавить прослушиватель кликов к элементу украшений, как показано ниже, но все равно не повезло. Пожалуйста помоги.
recyclerview.addOnItemTouchListener( object : RecyclerView.OnItemTouchListener{
override fun onTouchEvent(rv: RecyclerView?, e: MotionEvent?) {
}
override fun onInterceptTouchEvent(rv: RecyclerView?, e: MotionEvent?): Boolean {
val view = rv!!.findChildViewUnder(e!!.x, e!!.y)
if(view == null) return false
when(view.id){
R.id.list_item_section_text->{
Log.d("Clicked","Header")
}
}
return false
}
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
}
})
3 ответа
ItemDecoration
поможет вам нарисовать что-то между предметами, но View
вы рисуете на самом деле RecyclerView
сам (согласно Layout Inspector) через его Canvas
. Таким образом, вы не сможете добавить базовыйonClickListener
на этом украшения.
В соответствии с вашим кодом, я думаю, у вас есть украшение для каждого заголовка?
Для этого я бы не стал рассматривать мой заголовок как ItemDecoration
но как предмет (другого типа) я бы накормил RecyclerView
с.
sealed class RecyclerViewItem
object MainItem : RecyclerViewItem()
object Header : RecyclerViewItem()
В вашем адаптере (с элементами: RecyclerViewItem
) вы отменяете getItemViewType
метод с использованием пользовательских идентификаторов. Затем вonBindViewHolder
вы можете проверить тип представления элемента и добавить свой onClickListener
на ваш взгляд, если это Header
.
Для получения дополнительной информации вы можете выполнить поиск сборки RecyclerView с другим типом элемента.
Вы можете настроить RecyclerView и проверить, поступает ли сенсорное событие в ItemDecorator или нет:
class YourRecyclerView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {
private val clicksFlow: MutableSharedFlow<ClickEvent> = MutableSharedFlow(
extraBufferCapacity = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST
)
fun getClicksFlow() = clicksFlow as Flow<RecyclerClickEvent>
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(e: MotionEvent) : Boolean{
if (e.action == MotionEvent.ACTION_DOWN) {
for (i in 0 until itemDecorationCount) {
val decor = getItemDecorationAt(i)
if (decor is YourDecoration && decor.isOnTouched(this, e)) {
clicksFlow.tryEmit(ClickEvent(e.x, e.y))
return true
}
}
}
return super.onTouchEvent(e)
}
override fun onInterceptTouchEvent(e: MotionEvent): Boolean {
if (e.action == MotionEvent.ACTION_DOWN) {
for (i in 0 until itemDecorationCount) {
val decor = getItemDecorationAt(i)
if (decor is YourDecoration && decor.isOnTouched(this, e)) {
return true
}
}
}
return super.onInterceptTouchEvent(e)
}
}
class YourDecoration(/*some stuff*/) : RecyclerView.ItemDecoration() {
fun isOnTouched(parent: YourRecyclerView , e: MotionEvent): Boolean {
val w = abs(scaleX * width)
val h = abs(scaleY * height)
val top = topMargin - height / 2F - parent.paddingTop
return if (scaleX > 0) {
val side = parent.measuredWidth - sideMargin
e.y >= top && e.y <= (top + h) && side >= e.x && (side - w) <= e.x
} else {
val side = sideMargin
e.y >= top && e.y <= (top + h) && side <= e.x && e.x <= (side + w)
}
}
}
Вы можете добавить обратный вызов в адаптер, как показано ниже.
Сначала создайте интерфейс в классе Adapter:
public interface OnRecycleItemClickListener {
void onClick(View v, int position,String type);
}
Второй шаг - создание метода внутри класса адаптера для установки интерфейса.
public void setOnRecycleItemClickListener(OnRecycleItemClickListener onRecycleItemClickListener){
this.onRecycleItemClickListener = onRecycleItemClickListener;
}
Теперь установите onClick of Viewholder itemView.it является родительским макетом в каждом видоискателе.
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (onRecycleItemClickListener!=null)
onRecycleItemClickListener.onClick(view, viewHolder.getAdapterPosition(),"parent");
}
});
Для просмотра текста
viewHolder.textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (onRecycleItemClickListener!=null)
onRecycleItemClickListener.onClick(view, viewHolder.getAdapterPosition(),"textview");
}
});
Теперь установите интерфейс из действия или фрагмента, используя объект адаптера.
adapter.setOnRecycleItemClickListener(new BeaconListAdapter.OnRecycleItemClickListener() {
@Override
public void onClick(View v, int position,String type) {
if (type.equals("parent")){
}else if(type.equals("textview")){
}
}
});