Как передать лямбду в качестве дополнительного намерения? - PullRequest
1 голос
/ 14 февраля 2020

Я новичок в kotlin и Android, и я смотрел на recyclerView, но столкнулся с несколькими сбоями.
По существу, у меня есть,
+ 2 действия, MainActivity, содержащие recyclerView и действие fullDetails который открывается с помощью onClick на каждом тикете recyclerView, Действие A & Действие B
Fab-шоу показывает функцию, уникальную для каждого элемента, например, Toast, как в этом примере.
+ ArrayList объектов, tempMenuList из options class,
+ Класс содержит несколько строк и лямбда-переменную actionOfItem , как я хочу чтобы иметь индивидуальные функции для каждого объекта,
+ Я пытаюсь передать лямбду через намерение как сериализуемое через прослушиватель OnClick следующим образом:

val intent=Intent(context,fullDetails::class.java)
intent.putExtra("action",Runnable{tempMenuList[position].actionOfItem} as java.io.Serializable)

+ В действии B я получаю лямбду вот так и попробуйте вызвать функцию, так как это приводило к сбою моего приложения, я сделал отдельный класс actions для лямбды, чтобы я мог написать getSerializable () как объект actions * 102 3 * class.

val action=bundle.getSerializable("function") as actions?
fabShow.setOnClickListener{
          action?.action
    }

Теперь приложение загружает MainActivity, но вылетает при нажатии OnClickListner в RecyclerView.
Я знаю, что мое именование очень плохое и запутанное, и я не использую комментарии
но есть ли способ передать уникальную функцию для каждого объекта через намерение? Изменить 1: Я прочитал, что я могу сделать это с помощью SharedPreferences, но это не рекомендуется.
Вот Logcat:

java.lang.ClassCastException: com.example.androidreferenceapp.MainActivity$menuAdapter$onBindViewHolder$1$1 cannot be cast to java.io.Serializable
    at com.example.androidreferenceapp.MainActivity$menuAdapter$onBindViewHolder$1.onClick(MainActivity.kt:58)
    at android.view.View.performClick(View.java:6605)
    at android.view.View.performClickInternal(View.java:6582)
    at android.view.View.access$3100(View.java:778)
    at android.view.View$PerformClick.run(View.java:25897)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6762)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Вот полный исходный код, если это помогает

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Runnables не являются Сериализуемыми. Вы не можете просто привести все к Serializable, чтобы сделать его сериализуемым - это интерфейс, который вы должны реализовать. И вы не можете сериализовать ссылки на объекты, поэтому было бы невозможно сделать это с помощью функции.

Ваши данные (tempMenuList в данном случае) должны быть в ViewModel. Действия должны быть преобразованы во фрагменты, которые размещены в одной и той же деятельности. Первый фрагмент может просто передать индекс Int элемента в списке через намерение, а второй фрагмент может извлечь элемент и его action из ViewModel.

0 голосов
/ 14 февраля 2020

То, что вы пытаетесь сделать, это анти-паттерн. Вместо этого вы должны передать лямбду в качестве аргумента адаптеру переработчика, если это возможно. например,

//adapter class
class MyAdapter(
private val items: List<MyModel>,
private val clickListener: (item: MyModel) -> Unit
) :
RecyclerView.Adapter<MyAdapter.MyModelViewHolder>() {
   //adapter boilerplate
....
//viewholder class
inner class MyViewHolder(itemView: View) : 
RecyclerView.ViewHolder(itemView)
 fun bind(item: MyModel){
   itemView.setOnClickListener{
      clickListener(item)
    }
  }
}

Таким образом, вы можете обрабатывать события щелчка в действии, которое создало RecyclerView.

val myList = listOf(item1, item2...)
val adapter = MyAdapter(myList,  {item->
 //do whatever you want with item
})

Это дает вам большую гибкость и довольно прост в реализации.

Обратите внимание, что сериализация - очень дорогая вещь в android, поэтому были созданы Parcelables. Но в вашем случае вы можете избежать обоих.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...