Android: How to use viewbinding in base class and migrate from kotlin synthetics

With the deprecation of kotlin synthetics I faced the problem, that I can not access some standard layouts from my base class anymore. For example, I have a base class for three fragments and in all of them, there is a button. My old approach was to get the button in the base class with synthetics and then assign some default clicklistener etc.

My question is: What would be the best approach to migrate from the synthetics to viewbinding / databinding here? Another question I am asking my self is, how could I access the view_layouts outside the activity / fragment now?

Base class

abstract class BaseRebuildFragment(layout: Int) : Fragment(layout) {
    abstract val nextFragment: NavDirections
    abstract val baseViewModel: ViewModel
    open val dataOverViewFragment: Boolean = false
    @Inject @RebuildProgressDescription lateinit var progressBarDescription: ArrayList<String>

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initAppStandardToolbar()
        initStateProgressBar(progressBarDescription)
        initButton()
        hideBottomNav()
    }

    private fun initButton() {
        calibrate_btn_next.setOnClickListener { // not working anymore
            if (dataOverViewFragment) return@setOnClickListener else if (this.validForm()) findNavController().navigate(nextFragment)
        }
    }

    open fun validForm(): Boolean { return false }
}

Fragment

@AndroidEntryPoint
class RebuildOptionFragment : BaseRebuildFragment(R.layout.fragment_rebuild_option) {
    override val baseViewModel: RebuildViewModel by navGraphViewModels(R.id.nav_send_rebuild) { defaultViewModelProviderFactory }
    private val rebuildBinding: FragmentRebuildOptionBinding by viewBinding()
    override val nextFragment: NavDirections = RebuildOptionFragmentDirections.actionRebuildOptionFragmentToRebuildUserDataFragment()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        bindObjects()
        baseViewModel.setStateEvent(RebuildStateEvent.GetPrice)
        subscribeRebuildListObserver()
    }

    private fun bindObjects() = with(rebuildBinding) {
        viewModel = baseViewModel
        lifecycleOwner = viewLifecycleOwner
        lendingListener = LendingSwitch()
    }

    override fun validForm(): Boolean = baseViewModel.shippingValidator.isShippingOptionsValid()
}

Accessing view outside of activity / fragment in utils package

fun Fragment.initStateProgressBar(progressBarDescription: ArrayList<String>) = with(app_standard_progress_bar) { // not working anymore
    setStateDescriptionData(progressBarDescription)
}

fun Fragment.initAppStandardToolbar() {
    toolbar.setupWithNavController(findNavController(), AppBarConfiguration(findNavController().graph)) // not working anymore
}

Answer

findViewById can be used directly instead of using synthetics to accomplish the same thing, but without type safety. You have to provide the type since it won’t be able to infer the type.

fun Fragment.initStateProgressBar(progressBarDescription: ArrayList<String>) = with(requireView().findViewById<ProgressBar>(R.id.app_standard_progress_bar)) { 
    setStateDescriptionData(progressBarDescription)
}