RecyclerView 适配器中的导航组件
Navigation Component in RecyclerView Adapter
我在适配器中写了下面这段代码。
holder.itemView.setOnClickListener {
val action = SearchFragmentDirections.actionSearchFragmentToArtistFragment(artist.id)
Navigation.createNavigateOnClickListener(action)
}
这是五月导航xml:
...
<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>
但这行不通。有人可以帮忙吗?
您使用的是 lambda,它本身就是一个点击侦听器。
检查此 Navigation Docs,它使用导航 ID 和 createNavigationListener 正确实现了点击侦听器。
根据您的情况使用以下代码。
holder.itemView.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.action_searchFragment_to_artistFragment)
)
或者,试试这个方法
holder.itemView.setOnClickListener{ view ->
view.findNavController().navigate(R.id.action_searchFragment_to_artistFragment)
}
尝试通过您的片段与您的导航进行通信。因此,只需简单地创建从适配器到 Fragment/Activity 的回调,然后从 Fragment/Activity 尝试像普通方式一样使用导航方法。
在你的 RecyclerView Adapter OnBindViewHolder
方法中你可以这样做:
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);
});
在上面,目标是 SalonDetailFragment
,它的 ID 是 salonDetailFragment
并且将数据作为 Bundle
传递到目标。
我的导航配置
<?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>
kotlin 中的示例
对不起我的英语
尝试做一个点击界面,在Adapter内部使用,可以实现item的位置
example ==> interface
interface MyInterface {
fun OnClickListener( string : String , position: Int, view: View)
}
How to use inside the adapter
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)
}
}
}
afterwards and just make an implement inside the Fragment
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)
}
}
}
我认为最好将此添加到已接受的答案中:
holder.itemView.setOnClickListener(
Navigation
.createNavigateOnClickListener(R.id.action_searchFragment_to_artistFragment).onClick(holder.itemView)
)
如果你使用viewBinding,这就是连击
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)
}
基本上,您可以通过两种方式做到这一点。
您可以实例化 Navigation class 并创建导航点击侦听器
private fun openEditUser() {
binding.userName.setOnClickListener {
Navigation.createNavigateOnClickListener(R.id.addEditUserFragment)
}
}
您可以从按钮或您在项目布局中使用的任何其他元素获取视图,并使用 navigate 调用 findNavController ()方法
private fun openEditUser() {
binding.userName.setOnClickListener {
it.findNavController().navigate(R.id.addEditUserFragment)
}
}
在这两种情况下,您都需要引用用于导航的操作 ID,您可以在片段 XML 标签下的导航文件夹中看到该 ID
<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" />
如果您使用数据绑定,您只需
val 动作 = MessageListFragmentDirections.actionMessageListFragmentToSearchFragment()
binding.root.findNavController().导航(动作)
我在适配器中写了下面这段代码。
holder.itemView.setOnClickListener {
val action = SearchFragmentDirections.actionSearchFragmentToArtistFragment(artist.id)
Navigation.createNavigateOnClickListener(action)
}
这是五月导航xml:
...
<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>
但这行不通。有人可以帮忙吗?
您使用的是 lambda,它本身就是一个点击侦听器。 检查此 Navigation Docs,它使用导航 ID 和 createNavigationListener 正确实现了点击侦听器。
根据您的情况使用以下代码。
holder.itemView.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.action_searchFragment_to_artistFragment)
)
或者,试试这个方法
holder.itemView.setOnClickListener{ view ->
view.findNavController().navigate(R.id.action_searchFragment_to_artistFragment)
}
尝试通过您的片段与您的导航进行通信。因此,只需简单地创建从适配器到 Fragment/Activity 的回调,然后从 Fragment/Activity 尝试像普通方式一样使用导航方法。
在你的 RecyclerView Adapter OnBindViewHolder
方法中你可以这样做:
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);
});
在上面,目标是 SalonDetailFragment
,它的 ID 是 salonDetailFragment
并且将数据作为 Bundle
传递到目标。
我的导航配置
<?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>
kotlin 中的示例
对不起我的英语
尝试做一个点击界面,在Adapter内部使用,可以实现item的位置
example ==> interface
interface MyInterface {
fun OnClickListener( string : String , position: Int, view: View)
}
How to use inside the adapter
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)
}
}
}
afterwards and just make an implement inside the Fragment
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)
}
}
}
我认为最好将此添加到已接受的答案中:
holder.itemView.setOnClickListener(
Navigation
.createNavigateOnClickListener(R.id.action_searchFragment_to_artistFragment).onClick(holder.itemView)
)
如果你使用viewBinding,这就是连击
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)
}
基本上,您可以通过两种方式做到这一点。
您可以实例化 Navigation class 并创建导航点击侦听器
private fun openEditUser() { binding.userName.setOnClickListener { Navigation.createNavigateOnClickListener(R.id.addEditUserFragment) } }
您可以从按钮或您在项目布局中使用的任何其他元素获取视图,并使用 navigate 调用 findNavController ()方法
private fun openEditUser() { binding.userName.setOnClickListener { it.findNavController().navigate(R.id.addEditUserFragment) }
}
在这两种情况下,您都需要引用用于导航的操作 ID,您可以在片段 XML 标签下的导航文件夹中看到该 ID
<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" />
如果您使用数据绑定,您只需
val 动作 = MessageListFragmentDirections.actionMessageListFragmentToSearchFragment() binding.root.findNavController().导航(动作)