J'ai écrit le morceau de code suivant dans l'adaptateur.
... <fragment android:id="@+id/searchFragment" android:name="com.salmanseifian.spotiny.ui.search.SearchFragment" android:label="SearchFragment"> <action android:id="@+id/action_searchFragment_to_artistFragment" app:destination="@id/artistFragment" app:popUpTo="@+id/searchFragment"/> </fragment>
Et voici la navigation xml:
holder.itemView.setOnClickListener { val action = SearchFragmentDirections.actionSearchFragmentToArtistFragment(artist.id) Navigation.createNavigateOnClickListener(action) }
mais cela ne fonctionnera pas. Quelqu'un peut-il aider?
7 Réponses :
Vous utilisez lambda qui est lui-même un écouteur de clics. Vérifiez cette documentation de navigation qui a une implémentation correcte de l'écouteur de clic à l'aide de l'ID de navigation et de createNavigationListener.
Utilisez le code ci-dessous pour votre cas.
holder.itemView.setOnClickListener{ view -> view.findNavController().navigate(R.id.action_searchFragment_to_artistFragment) }
OU, essayez de cette façon
holder.itemView.setOnClickListener( Navigation.createNavigateOnClickListener(R.id.action_searchFragment_to_artistFragment) )
Malheureusement, cela n'a pas aidé. Le problème est toujours là.
La deuxième option a parfaitement fonctionné pour moi
Essayez de communiquer avec votre navigation dans votre Fragment. Créez simplement un rappel de votre adaptateur vers Fragment / Activity et depuis Fragment / Activity, essayez d'utiliser des méthodes de navigation comme de manière ordinaire.
Dans votre méthode OnBindViewHolder
adaptateur RecyclerView, vous pouvez l'avoir de cette façon:
<?xml version="1.0" encoding="utf-8"?> <navigation 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:id="@+id/mobile_navigation" android:label="Salon" app:startDestination="@+id/nav_home"> <fragment android:id="@+id/nearbySalonsFragment" android:name="my.package.NearbySalonsFragment" android:label="Nearby Salons" tools:layout="@layout/fragment_nearby_salons" > <action android:id="@+id/action_nearbySalonsFragment_to_salonDetailFragment" app:destination="@id/salonDetailFragment" /> </fragment> <fragment android:id="@+id/salonDetailFragment" android:name="my.package.SalonDetailFragment" android:label="Salon Details" tools:layout="@layout/fragment_salon_detail" /> </navigation>
Dans ce qui précède, la destination est SalonDetailFragment
dont l'id est salonDetailFragment
et transmet les données en tant que Bundle
à la destination.
Ma configuration de navigation
holder.bookBtn.setOnClickListener(view -> { Bundle bundle = new Bundle(); String salonJsonString = HelperMethods.getGsonParser().toJson(salonModel);bundle.putString("SALON_DETAILS", salonJsonString); Navigation.findNavController(view).navigate(R.id.salonDetailFragment,bundle); });
Exemple en kotlin
Désolé de mon anglais
Essayez de créer une interface de clic et de l'utiliser à l'intérieur de l'adaptateur, avec elle, vous pouvez prendre la position de l'élément
exemple ==> interface
class ProductFragment : Fragment(), MyInterface { lateinit var productAdadapter: ProductAdadapter companion object { fun newInstance() = ProductFragment() } private lateinit var viewModel: ProductViewModel override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.product_fragment, container, false) } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) viewModel = ViewModelProviders.of(this).get(ProductViewModel::class.java) viewModel.loadMessages().observe(viewLifecycleOwner, androidx.lifecycle.Observer { it?.let { grid.layoutManager = GridLayoutManager(context!!, 2) grid.adapter = ProductAdadapter(context!!, it, this) } }) mt_product_new.setOnClickListener { activity!!.onBackPressed() } } override fun OnClickListener(string: String, position: Int, view: View) { Navigation.findNavController(it) .navigate(R.id.action_my_orders_fragment_to_offers_fragment, null) } } }
Comment utiliser à l'intérieur de l'adaptateur
class ProductAdadapter( val context: Context, private var myInterface : MyInterface ) : RecyclerView.Adapter<ProductAdadapter.ProductViewModel>() { override fun onCreateViewHolder( parent: ViewGroup, viewType: Int ): ProductViewModel { val view = LayoutInflater.from(context).inflate(R.layout.item_product_adapter, parent, false) return ProductViewModel(view) } override fun getItemCount() = product.size override fun getItemViewType(position: Int): Int { return super.getItemViewType(position) } override fun onBindViewHolder(holder: ProductViewModel, position: Int) { holder.bindView(product[position]) holder.mcvProductsAd.setOnClickListener{ myInterface .OnClickListener(product[position],position, it) } } class ProductViewModel(item: View) : RecyclerView.ViewHolder(item) { val mcvProductsAd = item.mcv_products_ad fun bindView(product: Product) { Glide.with(itemView.context).load(product.image).into(imageProduct) } } }
ensuite et créez simplement un outil à l'intérieur du fragment
interface MyInterface { fun OnClickListener( string : String , position: Int, view: View) }
Je pense qu'il vaut mieux ajouter ceci à la réponse acceptée:
holder.itemView.setOnClickListener( Navigation .createNavigateOnClickListener(R.id.action_searchFragment_to_artistFragment).onClick(holder.itemView) )
Voilà la réponse.
si vous utilisez viewBinding, c'est la pâte
view.btnCategory.setOnClickListener { val navController= Navigation.findNavController((view.root.context) as Activity, R.id.nav_host_home) navController.navigate(R.id.action_movieFragment2_to_settingsFragment2) }
Pour une réponse plus belle, vous pouvez formater la partie du code en éditant la réponse. Ensuite, votre réponse sera plus facile à lire. Bienvenue dans stackOverflow :)
Fondamentalement, vous pouvez le faire de deux manières.
Vous pouvez instancier la classe de navigation et créer un écouteur de clic de navigation
<fragment android:id="@+id/addEditUserFragment" android:name="com.sajtek.user.xprsmartadmin.ui.add_edit_user.AddEditUserFragment" android:label="add_edit_user_fragment" tools:layout="@layout/add_edit_user_fragment" />
Vous pouvez obtenir la vue à partir du bouton ou de tout autre élément que vous utilisez dans la disposition de l'élément et appeler findNavController avec la méthode navigate ()
private fun openEditUser() { binding.userName.setOnClickListener { it.findNavController().navigate(R.id.addEditUserFragment) }
}
Dans les deux cas, vous aurez besoin d'une référence de l'ID de l'action qui sera utilisée pour la navigation, vous pouvez voir l'ID dans le dossier de navigation sous la balise XML fragment
private fun openEditUser() { binding.userName.setOnClickListener { Navigation.createNavigateOnClickListener(R.id.addEditUserFragment) } }
Êtes-vous sûr que
holder.itemView.setOnClickListener
est dansSearchFragment
?@JohnJoe Oui, j'en suis sûr.