How to access views added programmatically to a custom view?



I have created a custom class that extends from the MaterialCardView class, to which I add a TextView programmatically like this:

public class CustomQuestionView  extends MaterialCardView {

    private LinearLayout linearLayout;
    public TextView timeTextView;
    

  public CustomQuestionView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);

        this.linearLayout = new LinearLayout(context);
        LinearLayout.LayoutParams horizontalContentXLayoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        horizontalContentXLayoutParams.gravity = Gravity.CENTER;
        this.linearLayout.setLayoutParams(horizontalContentXLayoutParams);
        this.linearLayout.setOrientation(LinearLayout.VERTICAL);

        this.addView(linearLayout);

        this.timeTextView = new TextView(context);
        this.timeTextView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        this.timeTextView.setTextColor(Color.parseColor("#fcfc03"));
        this.timeTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 40);
        this.timeTextView.setText("What is your name?");
        this.linearLayout.addView(timeTextView);


   linearLayout.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "This is a test", Toast.LENGTH_SHORT).show();
            }
        });

    }


    public CustomQuestionView (Context context){
        super(context);
    }


    public void setQuestion(String question){
        this.timeTextView.setText(question);
    }


}

I create an instance of the CustomQuestionView in the onViewCreated() method of my fragment like this:

   @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        customQuestionView = new CustomQuestionView(requireContext());
      //  customQuestionView.setQuestion("Is this my custom question?");
        
    }

And my XML code for my fragment where the custom view is looks like this:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".customviews.CustomViewsFragment">
    

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:layout_gravity="center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:text="Welcome!"/>
        
        <com.pedroprojects.adc2.customviews.CustomQuestionView
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"/>
        
    </LinearLayout>
    
</FrameLayout>

The CustomQuestionView is created, and I get the initial text on the TextView showing on screen if I don’t make a call to the setQuestion() method, but the problem is that when I try to change the text by calling the setQuestion() method (when I uncomment the commented line on my onViewCreated() method), the app crashes and gives me the following error:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at com.pedroprojects.adc2.customviews.CustomQuestionView.setQuestion(CustomQuestionView.java:74)
        at com.pedroprojects.adc2.customviews.CustomViewsFragment.onViewCreated(CustomViewsFragment.java:51)

Why is my TextView null at the moment of invocation of this method, if I assign a value to it in the constructor? How do I need to access this TextView so that I can modify it after the CustomQuestionView is created?

Answer

The problem here is that the constructor where you are initializing the TextView is not invoked but rather the other constructor. So the timeTextView is null and when you try to invoke customQuestionView.setQuestion it causes a NullPointerException and crashes.



Source: stackoverflow