0

我有一个ParentFragment和一个ChildFragment。他们工作得很好。

我的问题是将来我可能会创建许多子片段,这使我为每个子片段编写此样板代码。因此,我想优化我的ParentFragment,这样我就不必为将来创建的每个新子框架编写样板代码。

ParentFragment

abstract class ParentFragment<T: ViewDataBinding>: Fragment() {

    @LayoutRes
    abstract fun getLayoutResId(): Int

    protected lateinit var binding: T

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        super.onCreateView(inflater, container, savedInstanceState)

        return DataBindingUtil.inflate<T>(inflater, getLayoutResId(), container, false).apply { binding = this }.root
    }

ChildFragment

class ChildFragment: ParentFragment<FragmentChildBinding>() {

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

        //THIS IS THE BOILERPLATE METHOD I AM TALKING ABOUT. 
        //I WOULD LIKE TO MOVE THIS CODE IN THE PARENTFRAGMENT
        initBinding() 
    }

    @LayoutRes
    override fun getLayoutResId() = R.layout.fragment_child

    fun initBinding() {
        val viewModel: ChildViewModel = getViewModel() //This method is from Koin
        binding.viewModel = viewModel
        binding.lifecycleOwner = this
    }

我试图将此initBinding方法代码移入ParentFragment,但出现错误。任何建议将不胜感激。

4

2 回答 2

0

因此,您当前的问题是您希望以initBinding()所有子片段都可以访问它的方式使您的功能通用。

现在的问题是内部逻辑initBinding带有动态解析的 koin 依赖项。因此,每个子片段可能有不同的 ViewModel 实例。


有一种方法可以解决此问题:

将您的ViewModel对象作为方法参数,以便您可以从子片段中注入它,同时在父片段中有方法。在下面查看如何:

initBinding()方法作为方法参数ParentFragmentviewModel我们将从子片段传递。

abstract class ParentFragment<T: ViewDataBinding>: Fragment() {

    // Other stuffs removed for sack of simplicity

    protected fun initBinding(viewModel: ViewModel) {
        binding.viewModel = viewModel
        binding.lifecycleOwner = this
    }
}

从以下位置访问它ChildFragment

class ChildFragment: ParentFragment<FragmentChildBinding>() {

    // Other stuffs removed for sack of simplicity

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

        // THIS IS HOW YOU CAN CONSUME THIS METHOD
        initBinding(getViewModel()) 
    }
}
于 2019-12-11T07:01:05.737 回答
0

您需要调用serVariable()您的binding对象以ViewModel在父片段中进行设置。如果子 Fragment 有自己的 ViewModel,则可以选择在您的父 Fragment 中通过抽象函数获取 ViewModel。

你可以关注这篇文章来解决你的问题。

于 2019-12-11T07:42:29.887 回答