You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据模型类型使用同一Adapter跳转至两个不同Fragment

解决RecyclerView不同条目类型跳转对应Fragment的问题

核心问题分析

当前FavoriteListAdapter的点击回调仅支持WordsWithMeanings类型,无法传递Proverb类型数据,导致无法触发对应Fragment的跳转。我们需要修改回调的参数类型,并在Fragment中根据条目类型分支处理跳转逻辑。


步骤1:修改FavoriteListAdapter的点击回调

将Adapter构造函数中的回调参数改为支持接收任意类型,同时为Proverb条目添加点击事件触发回调:

private const val WORD_VIEW_TYPE = 0
private const val PROVERB_VIEW_TYPE = 1

class FavoriteListAdapter(
    private val viewModel: WordViewModel,
    private val onItemClicked: (Any) -> Unit // 修改回调参数类型为Any
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    val mData = mutableListOf<Any>()

    // ... 其他原有代码不变

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val element = mData[position]
        when (getItemViewType(position)) {
            WORD_VIEW_TYPE -> {
                holder.itemView.setOnClickListener {
                    onItemClicked(element as WordsWithMeanings)
                }
                (holder as WordItemViewHolder).bind(element as WordsWithMeanings, viewModel)
            }
            PROVERB_VIEW_TYPE -> {
                // 新增Proverb条目的点击事件
                holder.itemView.setOnClickListener {
                    onItemClicked(element as Proverb)
                }
                (holder as ProverbItemViewHolder).bind(element as Proverb, viewModel)
            }
        }
    }

    // ... 其他原有代码不变
}

步骤2:在FavoriteFragment中处理不同类型的跳转

初始化Adapter时,在回调中判断点击条目的具体类型,分别触发对应Fragment的导航动作(需确保导航图中已定义actionFavouriteFragmentToProverbDetailFragment):

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    adapter = FavoriteListAdapter(viewModel) { item ->
        when(item) {
            is WordsWithMeanings -> {
                val action = FavoriteFragmentDirections.actionFavouriteFragmentToWordDetailFragment(item)
                findNavController().navigate(action)
            }
            is Proverb -> {
                val action = FavoriteFragmentDirections.actionFavouriteFragmentToProverbDetailFragment(item)
                findNavController().navigate(action)
            }
        }
    }

    // ... 其他原有代码不变
}

可选优化:用密封类提升类型安全性

如果想避免Any类型带来的强制转换风险,可以定义密封类统一条目类型,让代码更健壮:

1. 定义密封类

sealed class FavoriteItem {
    data class WordEntry(val data: WordsWithMeanings) : FavoriteItem()
    data class ProverbEntry(val data: Proverb) : FavoriteItem()
}

2. 修改Adapter的数据源和回调

class FavoriteListAdapter(
    private val viewModel: WordViewModel,
    private val onItemClicked: (FavoriteItem) -> Unit // 改为密封类类型
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    val mData = mutableListOf<FavoriteItem>() // 数据源改为密封类列表

    override fun getItemViewType(position: Int): Int {
        return when (mData[position]) {
            is FavoriteItem.WordEntry -> WORD_VIEW_TYPE
            is FavoriteItem.ProverbEntry -> PROVERB_VIEW_TYPE
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val element = mData[position]
        when (element) {
            is FavoriteItem.WordEntry -> {
                holder.itemView.setOnClickListener {
                    onItemClicked(element)
                }
                (holder as WordItemViewHolder).bind(element.data, viewModel)
            }
            is FavoriteItem.ProverbEntry -> {
                holder.itemView.setOnClickListener {
                    onItemClicked(element)
                }
                (holder as ProverbItemViewHolder).bind(element.data, viewModel)
            }
        }
    }

    // ... 其他原有代码不变
}

3. 修改Fragment中添加数据的逻辑

viewModel.allWordsWithMeanings.observe(this.viewLifecycleOwner) { items ->
    items.forEach {
        if (it.word.isFavorite == true) {
            adapter.mData.add(FavoriteItem.WordEntry(it))
        }
    }
    favoriteFragmentFavoriteStatus()
}

viewModel.allProverbs.observe(this.viewLifecycleOwner) { items ->
    items.forEach {
        if (it.isFavorite == true) {
            adapter.mData.add(FavoriteItem.ProverbEntry(it))
        }
    }
}

4. 修改Fragment中的跳转逻辑

adapter = FavoriteListAdapter(viewModel) { item ->
    when(item) {
        is FavoriteItem.WordEntry -> {
            val action = FavoriteFragmentDirections.actionFavouriteFragmentToWordDetailFragment(item.data)
            findNavController().navigate(action)
        }
        is FavoriteItem.ProverbEntry -> {
            val action = FavoriteFragmentDirections.actionFavouriteFragmentToProverbDetailFragment(item.data)
            findNavController().navigate(action)
        }
    }
}

内容的提问来源于stack exchange,提问作者oguzata

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 10:10:20