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?
Advertisement
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.