7

BaseFragment他の具象クラスによって拡張される抽象クラスを作成しましたFragment。を使用して注入ViewModelしたい。ここに私のBaseFragmentがあります:BaseFragmentKoin

abstract class BaseFragment<out VM : BaseViewModel, DB : ViewDataBinding>(private val mViewModelClass: Class<VM>) : Fragment() {

    val viewModel: VM by viewModel()

    open lateinit var binding: DB

    fun init(inflater: LayoutInflater, container: ViewGroup) {
        binding = DataBindingUtil.inflate(inflater, getLayoutRes(), container, false)
    }

    open fun init() {}
    @LayoutRes
    abstract fun getLayoutRes(): Int

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        init(inflater, container!!)
        init()
        super.onCreateView(inflater, container, savedInstanceState)
        return binding.root
    }

    open fun refresh() {}
} 

しかし、私はそうすることができません。2.0.1Koinのバージョンを使用しています。

4

2 に答える 2

2

私は現在、Koinのソースコードを見て、同じ問題を解決しており、by viewModel()kotlinを提供していますLazy

/**
 * Lazy get a viewModel instance
 *
 * @param qualifier - Koin BeanDefinition qualifier (if have several ViewModel beanDefinition of the same type)
 * @param parameters - parameters to pass to the BeanDefinition
 * @param clazz
 */
fun <T : ViewModel> LifecycleOwner.viewModel(
        clazz: KClass<T>,
        qualifier: Qualifier? = null,
        parameters: ParametersDefinition? = null
): Lazy<T> = lazy { getViewModel(clazz, qualifier, parameters) }

これは、初期化されると、viewModel インスタンスの実際の解決を行う別の LifecycleOwner 拡張メソッドを呼び出します。

/**
 * Lazy getByClass a viewModel instance
 *
 * @param clazz - Class of the BeanDefinition to retrieve
 * @param qualifier - Koin BeanDefinition qualifier (if have several ViewModel beanDefinition of the same type)
 * @param parameters - parameters to pass to the BeanDefinition
 */
fun <T : ViewModel> LifecycleOwner.getViewModel(
        clazz: KClass<T>,
        qualifier: Qualifier? = null,
        parameters: ParametersDefinition? = null
): T {
    return getKoin().getViewModel(
            ViewModelParameters(
                    clazz,
                    this@getViewModel,
                    qualifier,
                    parameters = parameters
            )
    )
}

試したことはありませんが、BaseFragment でこのメソッドを直接呼び出すと、同じように動作するはずです。BaseFragment は次のようになります。

abstract class BaseFragment<VM : ViewModel> : Fragment() {

    lateinit var viewModel: VM
    abstract val viewModelClass: KClass<VM>

    override fun onCreate(savedInstanceState: Bundle?) {
        viewModel = getViewModel(clazz = viewModelClass)

        super.onCreate(savedInstanceState)
    }

}
于 2019-08-18T20:09:30.597 に答える