android 如何根据型号类型使用相同适配器导航至2个不同片段?

b5lpy0ml  于 2022-12-09  发布在  Android
关注(0)|答案(1)|浏览(89)

我想根据我的模型类型使用相同的适配器导航2个不同的片段。但是我的问题是我不能处理两个不同模型的onItemClicked。正如你所看到的:

private val onItemClicked: (WordsWithMeanings) -> Unit

收藏片段

class FavoriteFragment : Fragment(R.layout.fragment_favorite) {

    private var _binding: FragmentFavoriteBinding? = null
 
    private val binding get() = _binding!!

    private val viewModel: WordViewModel by activityViewModels {
        WordViewModelFactory(
            (activity?.application as WordApplication).database.wordDao()
        )
    }

    private lateinit var adapter: FavoriteListAdapter
 
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentFavoriteBinding.inflate(inflater)
        return binding.root
    }

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

        adapter = FavoriteListAdapter(viewModel) {
            val action =          FavoriteFragmentDirections.actionFavouriteFragmentToWordDetailFragment(it). 
            this.findNavController().navigate(action)
        }

        binding.recyclerView.adapter = adapter

        viewModel.allWordsWithMeanings.observe(this.viewLifecycleOwner) { items ->
            items.let {
                for (i in items) {
                    if (i.word.isFavorite == true) {
                        adapter.mData.add(i)
                    }
                }
            }
            favoriteFragmentFavoriteStatus()
        }

        viewModel.allProverbs.observe(this.viewLifecycleOwner) { items ->
            items.let {
                for (i in items) {
                    if (i.isFavorite == true) {
                        adapter.mData.add(i)
                    }
                }
            }
        }

        binding.recyclerView.layoutManager = LinearLayoutManager(this.context)
    }
}`

**收藏夹列表适配器**

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

class FavoriteListAdapter(
private val viewModel: WordViewModel,
private val onItemClicked: (WordsWithMeanings) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

val mData = mutableListOf<Any>()

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    return when (viewType) {
        WORD_VIEW_TYPE -> WordItemViewHolder(
            FavoriteItemsBinding.inflate(
                inflater,
                parent,
                false
            )
        )
        PROVERB_VIEW_TYPE -> ProverbItemViewHolder(
            FavoriteItemsBinding.inflate(
                inflater,
                parent,
                false
            )
        )
        else -> throw IllegalArgumentException("Invalid view type")
    }
}

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 -> {
            (holder as ProverbItemViewHolder).bind(element as Proverb, viewModel)
        }
    }
}

class WordItemViewHolder(private var binding: FavoriteItemsBinding) :
    RecyclerView.ViewHolder(binding.root) {
    fun bind(favoriteWordsWithMeanings: WordsWithMeanings, viewModel: WordViewModel) {
        binding.apply {
            title.text = favoriteWordsWithMeanings.word.word
            content.text = favoriteWordsWithMeanings.means[0].wordMean
            favoriteButton.isChecked =
                favoriteWordsWithMeanings.word.isFavorite == true
            favoriteButton.setOnClickListener {
                if (favoriteButton.isChecked) {
                    favoriteButton.isChecked = true
                    viewModel.updateFavoriteWord(favoriteWordsWithMeanings, true)
                } else {
                    favoriteButton.isChecked = false
                    viewModel.updateFavoriteWord(favoriteWordsWithMeanings, false)
                }
            }
        }
    }
}

class ProverbItemViewHolder(private var binding: FavoriteItemsBinding) :
    RecyclerView.ViewHolder(binding.root) {
    fun bind(favoriteProverb: Proverb, viewModel: WordViewModel) {
        binding.apply {
            title.text = favoriteProverb.proverb
            content.text = favoriteProverb.proverbMean
            favoriteButton.isChecked =
                favoriteProverb.isFavorite == true
            favoriteButton.setOnClickListener {
                if (favoriteButton.isChecked) {
                    favoriteButton.isChecked = true
                    viewModel.updateFavoriteProverb(favoriteProverb, true)
                } else {
                    favoriteButton.isChecked = false
                    viewModel.updateFavoriteProverb(favoriteProverb, false)
                }
            }
        }
    }
}

override fun getItemCount(): Int {
    return mData.size
}

override fun getItemViewType(position: Int): Int {
    return when (mData[position]) {
        is WordsWithMeanings -> WORD_VIEW_TYPE
        is Proverb -> PROVERB_VIEW_TYPE
        else -> throw IllegalArgumentException("Unsupported type")
    }
}

}


所以我只导航到一个片段。我想做的是,如果点击的项目是'WordsWithMeanings',导航到WordDetailFragment,如果点击的项目是'Proverb',导航到ProverbDetailFragment。有合适的方法吗?
hyrbngr7

hyrbngr71#

您正在适配器onItemClicked回调中传递WordsWithMeaning项。您可以检查传递给回调的项是WordsWithMeaning类型还是Proverb类型,然后进行相应操作:

adapter = FavoriteListAdapter(viewModel) {
    val action = if (it is Proverb) {
        // navigate to proverb details
    } else {
        // navigate to word details
    }       
}

相关问题