Я хочу сделать BaseFragment. Для этого мне нужно использовать ViewDataBinding и ViewModel. используя общий, я могу использовать переменную, но не статическое поле. Например, мне нужно надуть, написав этот код «FragmentSecondBinding.inflate (layoutInflater, container, false)». Итак, я попробовал этот код «T.inflate (layoutInflater, container, false)», но получил некоторую ошибку. Также ViewModel похож на это. Как я могу преобразовать этот код в BaseCode?

abstract class BaseFragment<T: ViewDataBinding, M : ViewModel> : DaggerFragment(){

    abstract val layoutId : T
    private lateinit var  binding : T


    @Inject
    lateinit var viewModelFactory: ViewModelProvider.Factory

    private val viewModel by viewModels<M> { viewModelFactory }

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


        binding = T.inflate(inflater, container, false).apply {
            viewmodel = viewModel
        }
        return binding.root
    }


    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        binding.lifecycleOwner = this.viewLifecycleOwner
    }

0
jakchang 26 Мар 2020 в 07:57

1 ответ

Существует способ абстрагироваться от конкретного ViewDataBinding, однако для этого потребуется предоставить ссылку на ресурс макета для каждой конкретной реализации фрагмента:

protected abstract val layoutResource: Int

@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory

private val viewModel by viewModels<M> { viewModelFactory }

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


    binding = DataBindingUtil.inflate(inflater, layoutResource, container, false).apply {
        viewmodel = viewModel
    }
    return binding.root
}
0
Alex Kuzmin 26 Мар 2020 в 09:48