I have base activity implementing some features for every screen of my app. Every child activity then overrides method with its XML layout.
BaseActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.base_screen);
View mFormView = findViewById(R.id.pnContent);
if (getContentAreaLayoutId() != 0) {
LayoutInflater inflater = LayoutInflater.from(this);
View contentLayout = inflater.inflate(getContentAreaLayoutId(), (ViewGroup) mFormView, false);
((ViewGroup) mFormView).addView(contentLayout, 0);
}
}
ChildActivity
override fun getContentAreaLayoutId(): Int = R.layout.standard_content_settings
Now I would like to use view binding in my child activities. I was thinking about something like this:
override fun onCreate(savedInstanceState: Bundle?) {
val binding = StandardContentSettingsBinding.inflate(layoutInflater)
}
But when I used binding (binding.edURL.setText("test")
), view does not change and stays empty. I guess I'm using view binding wrong and have to inflate it with another way?
You can inflate the binding object in the BaseActivity
and expose methods to child activities to get the binding object.
public abstract class BaseActivity extends AppCompatActivity {
//base binding
private BaseScreenBinding baseBinding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // always call base methods, your code didnt have those calls.
baseBinding = BaseScreenBinding.inflate(getLayoutInflater());
setContentView(baseBinding.getRoot());
//your existing code to inflate child content
View mFormView = baseBinding.pnContent;
if (getContentAreaLayoutId() != 0) {
LayoutInflater inflater = LayoutInflater.from(this);
View contentLayout = inflater.inflate(getContentAreaLayoutId(), (ViewGroup) mFormView, false);
((ViewGroup) mFormView).addView(contentLayout, 0);
}
}
protected BaseScreenBinding getBaseBinding() {
return baseBinding;
}
protected abstract int getContentAreaLayoutId();
}
you can now use ViewBinding in your child activity, your layout was inflated by BaseActivity, in child you will bind to it.
class ChildActivity : BaseActivity() {
private lateinit var binding: StandardContentSettingsBinding
override fun getContentAreaLayoutId(): Int = R.layout.standard_content_settings
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Layout was inflated in BaseActivity, so now only bind to it.
binding = StandardContentSettingsBinding.bind(getBaseBinding().pnContent)
//This should work now
binding.edURL.setText("test")
}
}
In the child activity, calling StandardContentSettingsBinding.bind(View)
, is different from inflate()
, as it doesn't create a new view hierarchy but instead uses the existing one, which is what you want in this case.
some references: https://developer.android.com/topic/libraries/data-binding/generated-binding