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

时间:2021-06-30 09:14:15

标签: android kotlin viewmodel factory

我需要从我的片段中的参数中获取参数并将其提供给视图模型,以便它根据它与否过滤列表。我认为可以将此参数传递给视图模型的工厂,并从那里传递给视图模型本身的构造函数,因此它将具有 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 }
        }
    }
}

我需要你帮忙写代码。我在心里明白怎么做,但我不知道怎么写。如果能提供带有解释的书面示例,我将不胜感激。

1 个答案:

答案 0 :(得分:1)

这并不像看起来那么难;只需在 ContentViewModel 中创建一个新的公共变量

var isFavorite: Boolean = false

然后将您的获取逻辑放在方法中,而不是 ViewModel 的 init。

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 的值。

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

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