Custom views for kids are null after inflating views in Android

I am working on an Android application. 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 inflate the view (I tried both of the 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 encountered when view.setCard (card) is called, I see that textView is null, although I expect it to be set in the init (..) method. Can someone tell me that it is not configured correctly? Thanks in advance.

+6
source share
2 answers

Thank you for your responses. It turns out that init (context) should not be called in the constructor. The correct place to call is in onFinishInflate (). The following changes helped fix this:

 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()); } } 
+12
source

Instead of using the 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, where you want to place

 <com.hello.view.card.inner.SimpleCardView /> 

and any properties it needs, its identifier, its width / height, etc.

+1
source

Source: https://habr.com/ru/post/971446/


All Articles