I am working on an Android app. I have a custom view and layout as follows:
<com.hello.view.card.inner.SimpleCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/card_simple_linear_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/simple_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</com.hello.view.card.inner.SimpleCardView>
And this is the Java class:
public class SimpleCardView extends LinearLayout {
protected SimpleCard card = null;
protected TextView textView;
public SimpleCardView(Context context) {
super(context);
init(context);
}
public SimpleCardView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SimpleCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
protected void init(Context context) {
textView = (TextView)findViewById(R.id.simple_label);
}
public void setCard(SimpleCard card) {
this.card = card;
textView.setText(card.getMessage());
}
}
And this is how I am inflating the view (I tried both following calls):
SimpleCardView view = (SimpleCardView)inflater.inflate(R.layout.card_simple, null);
//SimpleCardView view = (SimpleCardView)inflater.inflate(R.layout.card_simple, parent);
view.setCard(card);
The problem I am having is when view.setCard(card) is called, I see that textView is null, even though I am expecting it to be set in the init(..) method. Can anyone tell me what it not being set correctly? Thanks in advance.
Your custom view can also extend View directly, or you can save time by extending one of the existing view subclasses, such as Button . To allow Android Studio to interact with your view, at a minimum you must provide a constructor that takes a Context and an AttributeSet object as parameters.
In this context, Inflate means reading a layout XML (often given as parameter) to translate them in Java code. This process happens: in an activity (the main process) or a fragment.
Some examples of default views present in the Android Framework are EditText, TextView, Button, CheckBox, RadioButton, etc. ViewGroup is a special view that can contain other views (called children). We can create custom views and use them in our Application.
LayoutInflater is used to create a new View (or Layout ) object from one of your xml layouts. findViewById just gives you a reference to a view than has already been created.
Thank you for your answers. It turns out init(context) should not be called in the constructor. The right place to call it is in onFinishInflate(). The following change helped fix it:
public class SimpleCardView extends LinearLayout {
protected SimpleCard card = null;
protected TextView textView;
public SimpleCardView(Context context) {
super(context);
}
public SimpleCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SimpleCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
init(getContext());
}
protected void init(Context context) {
textView = (TextView)findViewById(R.id.simple_label);
}
public void setCard(SimpleCard card) {
this.card = card;
textView.setText(card.getMessage());
}
}
Instead of using root element
com.hello.view.card.inner.SimpleCardView
try using
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/simple_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</merge>
then, in your init method
LayoutInflater.from(context).inflate(R.layout.card_simple, this);
setOrientation(LinearLayout.VERTICAL);
textView = (TextView)findViewById(R.id.simple_label);
When you use the view in other layouts, that's where you will want to put
<com.hello.view.card.inner.SimpleCardView />
and any properties that it needs, its id, its width/height, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With