I have a custom view "BallHoldView" which is run from an activity "BallHoldActivity" by adding said view to the BallHoldActivity layout resource within merge tags. Also within the same layout xml is a TextView (scoreText). I want to set scoreText's text dynamically from the BallHoldView. When my program tries to run scoreText.setText("new text here"); I get a view.InflateException. Commenting out this one line of code removes the errors.
Through online research I have identified the following:
Can anyone see what I'm missing, or what I've done wrong?
Main errors seem to be:
android.view.InflateException: Binary XML file line #12: Error inflating class
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.NullPointerException
xml line #12 (& #13):
<oaa.tms.zoneball.ballHold.BallHoldView
android:id="@+id/ballHold"
Null Pointer is at BallHoldView.java:37 which is:
scoreText.setText("New Score"); // java line 37.
Here's BallHoldView:
public class BallHoldView extends View
{
private ShapeDrawable circle10, circle50, circleEYE;
private TextView scoreText;
private int viewWidth, viewHeight;
private float circCentreX, circCentreY, circ10Radius, circ50Radius, circEyeRadius;
public BallHoldView(Context context)
{
super(context);
}
public BallHoldView(Context context, AttributeSet attrs)
{ super(context, attrs);
Log.e("BallHoldView", "CONSTRUCTOR ENTERED");
circle10 = new ShapeDrawable(new OvalShape());
circle10.getPaint().setColor(0xffff9900);
circle50 = new ShapeDrawable(new OvalShape());
circle50.getPaint().setColor(0xffb80000);
circleEYE = new ShapeDrawable(new OvalShape());
circleEYE.getPaint().setColor(0xff000000);
scoreText = (TextView)((Activity)getContext()).findViewById(R.id.scoreText);
Log.e("BallHoldView", "scoreText created");
scoreText.setText("New Score");
Log.e("BallHoldView", "scoreText changed");
}
public void onDraw(Canvas c)
{
super.onDraw(c);
// Draw some circles here
}
protected void onSizeChanged(int w, int h, int oldW, int oldH)
{
// change circle parameters here
}
}
Here's the xml:
<merge 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"
android:background="@drawable/shape_rect_black_border"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="oaa.tms.zoneball.BallHoldActivity" >
<oaa.tms.zoneball.ballHold.BallHoldView
android:id="@+id/ballHold"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView
android:id="@+id/scoreText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|left"
android:background="@drawable/shape_rect_textbg"
android:textSize="22sp"
android:text="@string/score" />
<TextView
android:id="@+id/timeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|right"
android:background="@drawable/shape_rect_textbg"
android:textSize="22sp"
android:text="@string/time" />
</merge>
Here's the log cat (errors):
10-05 17:44:04.326: E/BallHoldView(3474): CONSTRUCTOR ENTERED
10-05 17:44:04.326: E/BallHoldView(3474): scoreText created
10-05 17:44:04.336: E/AndroidRuntime(3474): FATAL EXCEPTION: main
10-05 17:44:04.336: E/AndroidRuntime(3474): java.lang.RuntimeException: Unable to start activity ComponentInfo{oaa.tms.zoneball/oaa.tms.zoneball.BallHoldActivity}: android.view.InflateException: Binary XML file line #12: Error inflating class oaa.tms.zoneball.ballHold.BallHoldView
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2249)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2299)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.ActivityThread.access$700(ActivityThread.java:154)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.os.Handler.dispatchMessage(Handler.java:99)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.os.Looper.loop(Looper.java:137)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.ActivityThread.main(ActivityThread.java:5306)
10-05 17:44:04.336: E/AndroidRuntime(3474): at java.lang.reflect.Method.invokeNative(Native Method)
10-05 17:44:04.336: E/AndroidRuntime(3474): at java.lang.reflect.Method.invoke(Method.java:511)
10-05 17:44:04.336: E/AndroidRuntime(3474): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
10-05 17:44:04.336: E/AndroidRuntime(3474): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
10-05 17:44:04.336: E/AndroidRuntime(3474): at dalvik.system.NativeStart.main(Native Method)
10-05 17:44:04.336: E/AndroidRuntime(3474): Caused by: android.view.InflateException: Binary XML file line #12: Error inflating class oaa.tms.zoneball.ballHold.BallHoldView
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.view.LayoutInflater.createView(LayoutInflater.java:619)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:693)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.view.LayoutInflater.rInflate(LayoutInflater.java:752)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.view.LayoutInflater.inflate(LayoutInflater.java:460)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
10-05 17:44:04.336: E/AndroidRuntime(3474): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:342)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.Activity.setContentView(Activity.java:1928)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.support.v7.app.ActionBarActivity.superSetContentView(ActionBarActivity.java:217)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.support.v7.app.ActionBarActivityDelegateICS.setContentView(ActionBarActivityDelegateICS.java:110)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:77)
10-05 17:44:04.336: E/AndroidRuntime(3474): at oaa.tms.zoneball.BallHoldActivity.onCreate(BallHoldActivity.java:17)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.Activity.performCreate(Activity.java:5255)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2213)
10-05 17:44:04.336: E/AndroidRuntime(3474): ... 11 more
10-05 17:44:04.336: E/AndroidRuntime(3474): Caused by: java.lang.reflect.InvocationTargetException
10-05 17:44:04.336: E/AndroidRuntime(3474): at java.lang.reflect.Constructor.constructNative(Native Method)
10-05 17:44:04.336: E/AndroidRuntime(3474): at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
10-05 17:44:04.336: E/AndroidRuntime(3474): at android.view.LayoutInflater.createView(LayoutInflater.java:593)
10-05 17:44:04.336: E/AndroidRuntime(3474): ... 25 more
10-05 17:44:04.336: E/AndroidRuntime(3474): Caused by: java.lang.NullPointerException
10-05 17:44:04.336: E/AndroidRuntime(3474): at oaa.tms.zoneball.ballHold.BallHoldView.<init>(BallHoldView.java:37)
10-05 17:44:04.336: E/AndroidRuntime(3474): ... 28 more
EDIT: Using the following code I have confirmed scoreText is null:
scoreText = (TextView)((Activity)getContext()).findViewById(R.id.scoreText);
Log.e("BallHoldView", "scoreText created");
if(scoreText != null)
{
scoreText.setText("New Score");
Log.e("BallHoldView", "scoreText changed");
}
else
Log.e("BallHoldView", "scoreText was null");
Why is it null?
The problem is that your code at line # 37
scoreText.setText("New Score");
scoreText
is null
.
scoreText = (TextView)((Activity)getContext()).findViewById(R.id.scoreText);
The above line is not able to find the scoreText
. This might be because when the custom view layout is inflated, it will call its constructor, and in there you are trying to refer scoreText
which has not been inflated yet, as it comes after ballHold
in your android xml.
The solution might be to put the ballHold
custom view after your scoreText
in android xml. Or otherwise the proper way would be to pass the scoreText
TextView from your java activity code to the BallHoldView
CustomView class in its constructor and then use it. In that case, in your activity code you will definitely be able to find view by id.