如何将参数传递给视图模型?

How do I pass an argument to the view model?

我需要从片段中的参数中获取参数并将其提供给视图模型,以便它根据它过滤列表。我认为可以将此参数传递给视图模型的工厂,然后从那里传递给视图模型本身的构造函数,因此它将具有 val onlyFavorites 并且可以立即在 init 块中使用。

ContentFragment.kt

class ContentFragment : Fragment(), ItemFavoriteClickListener {

    private val viewModel: ContentViewModel by viewModels(factoryProducer = {
        ContentViewModel.Factory()
    })

    private var adapter: MyItemModelsAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.getBoolean("onlyFavorites", false)
        
        viewModel.items.observe(this) {
            adapter?.items = it
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        recyclerView?.layoutManager = LinearLayoutManager(context)

        adapter = MyItemModelsAdapter(this)
        recyclerView?.adapter = adapter
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_favourites, container, false)
    }

    override fun onFavoriteClick(item: ItemModel, isFavorite: Boolean) {
        viewModel.changeFavoriteState(item, isFavorite)
    }

    companion object {
        fun newInstance(onlyFavorites: Boolean): ContentFragment {
            val contentFragment = ContentFragment()
            val args = Bundle()
            args.putBoolean("onlyFavorites", onlyFavorites)
            contentFragment.arguments = args

            return contentFragment
        }
    }
}

ContentViewModel.kt

class ContentViewModel(
    private val repository: MyItemsRepository
) : ViewModel() {

    class Factory : ViewModelProvider.Factory {
        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
            return ContentViewModel(MyItemsRepositoryImpl.getInstance()) as T
        }
    }

    private val _items: MutableLiveData<List<ItemModel>> = MutableLiveData()
    val items: LiveData<List<ItemModel>>
        get() = _items

    fun changeFavoriteState(item: ItemModel, favorite: Boolean) {
        repository.setFavorite(item, favorite)
    }

    init {
        _items.value = repository.items.filter { it.isFavorite }
        repository.addItemChangeListener {
            _items.value = repository.items.filter { it.isFavorite }
        }
    }
}

我需要你帮助编写代码。我心里明白怎么做,但我不知道怎么写。我将非常感谢一个带有解释的书面示例。

这并不像看起来那么难;只需在您的 ContentViewModel

中创建一个新的 public 变量

var isFavorite: Boolean = false

然后不要初始化 ViewModel,而是将您的抓取逻辑放在一个方法中。

fun getItems() {
    _items.value = repository.items.filter { it.isFavorite == isFavorite }
}

现在在片段的 onViewCreated() 中调用此方法,如下所示:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    recyclerView?.layoutManager = LinearLayoutManager(context)

    adapter = MyItemModelsAdapter(this)
    recyclerView?.adapter = adapter

    val isFavorite = arguments?.getBoolean("onlyFavorites", false) ?: false
    viewModel.isFavorite = isFavorite

    viewModel.getItems()
    
    viewModel.items.observe(this) {
        adapter?.items = it
    }
}

这样,在实际调用 getItems 方法之前,您就获得了 isFavorite 的值。

我还没有测试过这段代码,但我很确定它会起作用。

如果您需要更多帮助,请发表评论。