So, I've done some research and it seems that view inflation within the init
/constructor of an abstract base class is not really a best practice. I understand that's because the base class initializer happens before the init
/constructor of the derived class. Since the abstract class is non-final there's a nice IDE message about this
being leaked in the init
block.
Here is what I'm after though:
abstract class Foo @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
private val myView: View
init {
// todo@patches fix leaking "this"
View.inflate(context, R.layout.view_foo, this)
myView = requireNotNull(findViewById(R.id.my_view))
}
}
class Bar @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : Foo(context, attrs, defStyleAttr)
I really don't want to have to add anything to the init of the derived class or make myView
a nullable/mutable variable that is set later in the abstract class.
Does anyone else find this slightly frustrating or have any advice? It seems like it would be not uncommon to want to inflate the same layout from a base class.