BaseViewBindingActivity:
abstract class BaseBindingActivity<VB : ViewBinding> : AppCompatActivity() {
protected lateinit var binding: VB
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(withGenericBindingClass<VB>(this) { clazz ->
clazz.getMethod("inflate", LayoutInflater::class.java).invoke(null, layoutInflater) as VB
}.also { binding = it }.root)
}
private fun <VB : ViewBinding> withGenericBindingClass(any: Any, block: (Class<VB>) -> VB): VB {
var genericSuperclass = any.javaClass.genericSuperclass
var superclass = any.javaClass.superclass
while (superclass != null) {
if (genericSuperclass is ParameterizedType) {
genericSuperclass.actualTypeArguments.forEach {
try {
return block.invoke(it as Class<VB>)
} catch (e: NoSuchMethodException) {
} catch (e: ClassCastException) {
} catch (e: InvocationTargetException) {
throw e.targetException
}
}
}
genericSuperclass = superclass.genericSuperclass
superclass = superclass.superclass
}
throw IllegalArgumentException("There is no generic of ViewBinding.")
}
}
BaseDataBindingFragment:
open class BaseDataBindingFragment<DB : ViewDataBinding> : Fragment() {
var binding: DB? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return withGenericBindingClass(this) {
it.getMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java)
.invoke(null, layoutInflater, container, false) as? DB
}.also { binding = it }?.root
}
private fun <DB> withGenericBindingClass(any: Any, block: (Class<DB>) -> DB): DB {
var genericSuperclass = any.javaClass.genericSuperclass
var superclass = any.javaClass.superclass
while (superclass != null) {
genericSuperclass.let { it as? ParameterizedType }?.actualTypeArguments?.forEach {
return block.invoke(it as Class<DB>)
}
genericSuperclass = superclass.genericSuperclass
superclass = superclass.superclass
}
throw IllegalArgumentException("There is no generic of DataBinding.")
}
override fun onDestroyView() {
binding?.unbind()
binding = null
super.onDestroyView()
}
}