ViewModels for image transformations
kotlinify getViewModel

I would change

protected fun &lt;T: ViewModel&gt;getViewModel(c: Class&lt;T&gt;): T
            = ViewModelProviders.of(activity)[c]
}
//with 
protected fun &lt;T: ViewModel&gt;getViewModel(c: KClass&lt;T&gt;): T
            = ViewModelProviders.of(activity)[c.java]
}


after replacing the Class with KClass in the activity, you can use the kotlin ones instead of the java-ones.

then you can use:

private typealias RVM = RotateViewModel
private typealias CVM = CropViewModel
class CropFragment: BaseFragmentInOut&lt;CVM, RVM&gt;(CVM::class, RVM::class) {
    ...
}


second example

In your second example, you tell me you must do everything in the Cropfragment.
This isn't true as your Basefragment can have those fields and the parent can set them.

abstract class BaseFragmentInOut&lt;InVM : BitmapViewModel, OutVM : BitmapViewModel : BaseFragment() {
    protected lateinit var inViewModel: InVM
    protected lateinit var outViewModel: OutVM
    fun getInBitmap(): Bitmap = inViewModel.bitmap
    fun setOutBitmap(bmp: Bitmap) { outViewModel.bitmap = bmp }

    @CallSuper
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        inViewModel = getViewModel(c1)
        outViewModel = getViewModel(c2)
    }
}


and in your CropFragment:

class CropFragment: BaseFragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        inViewModel = getViewModel()   //changes the field in BaseFragment
        outViewModel = getViewModel() //changes the field in BaseFragment
    }
}


template method

If you don't want to have onViewCreated in the basefragment or you want to de other things after having set the viewmodels in onViewCreated in the basefragment, use a template method:

create an abstract method in the super-class that should do what you want... In this case create the ViewModels

abstract class BaseFragmentInOut&lt;InVM : BitmapViewModel, OutVM : BitmapViewModel : BaseFragment() {
    abstract fun createInViewModel() : InVM
    abstract fun createOutViewModel() : OutVM

    @CallSuper
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        inViewModel = createInViewModel()
        outViewModel = createOutViewModel()
    }
}


your sub-class is then forced to implement them:

class CropFragment: BaseFragment() {
    override fun createInViewModel() = getViewModel()
    override fun createOutViewModel() = getViewModel()
}


to much?

You can of course also combine both the template methods to one called createViewModels.
Then you can create a helper-function in BaseFragmentInOut:

protected inline fun &lt;reified I : InVM, reified O : OutVM&gt;  initialize(){
    inViewModel = getViewModel(I::class)
    outViewModel = getViewModel(O::class)
}


The only thing you have to do at that moment is to implement createViewModels the following way:

override fun createViewModels() = initialize&lt;RVM, CVM&gt;()


At the moment it's not possinle to remove RVM and CVM from the initialize, but it's on the table