Как использовать лямбду вместо интерфейса kotlin - PullRequest
0 голосов
/ 28 января 2019

У меня в Android есть адаптер для просмотра рециркуляции.Часть моего класса адаптера выглядит следующим образом:

private lateinit var itemLongClick: ItemLongClick

override fun onCreateViewHolder(parent: ViewGroup, a: Int): RecyclerAdapter.ViewHolder {

      // Define And Initialize The Custom View And Its Holder//
      val myView = LayoutInflater.from(parent.context).inflate(customLayout, parent, false)
      val viewHolder = ViewHolder(myView)

      // What Happens When A List Item Is Long Clicked//
      myView.setOnLongClickListener { view ->

          // Differ Action To Class Instance//
          itemLongClick.longClicked(context, viewHolder.layoutPosition, view)

          // End Function//
          true
      }

      // Returns The Custom View//
      return viewHolder
}

fun setItemLongClick(itemLongClick: ItemLongClick) {

    // Sets The Value For this.itemLongClick//
    this.itemLongClick = itemLongClick
}    

Я создал интерфейс, похожий на этот:

interface ItemLongClick {

    // Function Declaration For When An Item Is Long Clicked//
    fun longClicked(context: Context, position: Int, view: View)
}

Вместо того, чтобы писать свой длинный код клика в классе адаптера, который я хочучтобы отличать его от действия, которое вызывает класс адаптера.Я знаю, что один из способов сделать это - создать интерфейс kotlin, а затем вызвать его в другом классе, как этот

  userAdapter.setItemLongClick(object: ItemLongClick {
        override fun longClicked(context: Context, position: Int, view: View) {

        }
    })

Но это выглядит грязно.Я знаю, что Java-интерфейсы работают с SAM, но я тоже не хочу этого делать.Я хочу, чтобы onLongClick был лямбда-выражением, но я не уверен, как настроить лямбда-выражение Kotlin, чтобы это работало, и я нигде не могу найти хороший пример.

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 28 января 2019

У меня был адаптер, который мне нужен для изменения данных на основе коммутатора, и я сделал что-то вроде этого:

ListAdapter(private val context: Context, private val switchListener: (Boolean) -> Unit)

Затем, где я связал заголовок моего секционированного списка, у меня было:

private fun bindHeader(holder: HeaderViewHolder) {
        holder.switch.setOnCheckedChangeListener { _, isChecked ->
            callbackSwitchListener(isChecked)
        }
    }

И в моем фрагменте:

private fun setupRecyclerView() {
        fabricationDataListAdapter =
                FabricationDataListAdapter(context!!) { isChecked: Boolean -> switchControl(isChecked) }
        val layoutManager = ListLayoutManager(context!!)
        this.recycler_view_all.layoutManager = layoutManager
        this.recycler_view_all.adapter = fabricationDataListAdapter
    }

Где забавный switchControl изменил данные на основе логического значения.

Я не уверен, что это то, что вам нужно,Я немного спешу, но это называется функциями высокого порядка в kotlin, если я не ошибаюсь.

0 голосов
/ 28 января 2019

У вас есть два варианта:

1.) Заменить интерфейс typealias

typealias ItemLongClick = (Context, Int, View) -> Unit

2.) Добавить функцию расширения для установки интерфейса в качестве лямбды вместо анонимного объекта

inline fun UserAdapter.setItemLongClick(crossinline longClick: (Context, Int, View) -> Unit) {
    setItemLongClick(object: ItemLongClick {
        override fun longClicked(context: Context, position: Int, view: View) {
            longClick(context, position, view)
        }
    })
}

Теперь вы можете звонить

userAdapter.setItemLongClick { context, position, view -> 
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...