Bonjour,
J'ai créé un fragment générique qui se contente d'initialiser une vue (RecyclerView + Adapter). Les données de l'adapter sont récupérées via un webservice que j'attaque par l'intermédiaire de la librairie Volley.
Sur mon activité principale, j'utilise un NavController et la méthode navigate() afin de naviguer d'une page à une autre (mais toujours au travers du fragment générique). Lors de la navigation, j'envoi un paramètre "action" et un paramètre "id" qui permettront de spécifier auprès du webservice les données à récupérer.
Ce fonctionnement marche bien.
Seulement maintenant, il faut que je puisse faire des traitements spécifiques selon les pages où je me trouve. Dans mon fragment, j'ai donc déclaré une méthode "setOnTouch" que j'utilise pour initialiser l'événement qui se produira lorsque l'utilisateur touchera un élément de ma RecyclerView :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 class CustomAdapter() : RecyclerView.Adapter<CustomAdapter.ViewHolder>() { private lateinit var onTouch: (result: JSONObject) -> Unit [...] fun setOnTouch(touchEvent: (result: JSONObject) -> Unit){ this.onTouch = touchEvent } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val v: View = LayoutInflater.from(parent.context).inflate(mLayout, parent, false) v.setOnClickListener { view -> if (this::onTouch.isInitialized) if (view.tag is JSONObject) this.onTouch(view.tag as JSONObject) } return ViewHolder(v) } [...] }Ma question est la suivante : comment passer une méthode (lambda) via la méthode navigate() :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 class DataListFragment(action: String, id: String): Fragment() { private var ad = CustomAdapter(customLayout) [...] fun setOnTouch(clickEvent: (result: JSONObject) -> Unit){ this.ad.setOnTouch(clickEvent) } [...] }
J'ai essayé simplement ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 val bundle = Bundle() bundle.putString("action","clients") bundle.putString("id","1234") bundle.put?????? {result: JSONObject -> //Traitement de l'enregistrement } findNavController(R.id.nav_host_fragment).navigate(R.id.nav_test, bundle)
Mais ça marche pas... J'ai essayé de créer une classe qui hérite de Bundle, pour créer une propriété "onTouch" mais impossible : la classe Bundle est déclarée par Google comme Final...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 bundle.putSerializable { result: JSONObject -> } as Serializable
J'ai ensuite créé une data classe de type Parcelable :
Puis dans mon activité :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 @Parcelize data class ListDataBundle( var action: String, var id: String, var touchEvent: Serializable ) : Parcelable {}
Et dans mon fragment récupérer la fonction comme ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 bundle.putParcelable("data", ListDataBundle("clients","1234",{ result: JSONObject -> } as Serializable))
Mais à chaque fois j'ai cette fichue erreur "IOException writing serializable object" qui, à mon avis, signifie qu'on ne peut pas sérialiser le type (result: JSONObject) -> Unit...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 val monParcelable = this.arguments?.getParcelable("data") as ListDataBundle this.ad.setOnTouch(monParcelable.touchEvent as (result: JSONObject) -> Unit)
Je suis un peu à court d'idées... Certainement dû au fait que je débute en Kotlin et que je suis loin de maitriser encore les principaux concepts...
De l'aide ne serait pas de refus
Partager