自定义视图中带有动态setText的android.view.InflateException

时间:2014-10-05 05:13:34

标签: android xml inflate-exception

我有一个自定义视图" BallHoldView"这是从一项活动" BallHoldActivity"通过将所述视图添加到合并标记内的BallHoldActivity布局资源。同样在布局中,xml是TextView(scoreText)。我想从BallHoldView动态设置scoreText的文本。 当我的程序试图运行scoreText.setText时("这里的新文本");我得到一个view.InflateException。注释掉这一行代码可以消除错误。

通过在线研究,我发现了以下内容:

  • 我的BallHoldView需要一个传递给它的Attributes的构造函数。 (校验)
  • 我的scoreText需要参考活动而不是视图进行实例化:((Activity)getContext())。findViewById(R.id.scoreText); (校验)
  • 此异常的大多数问题似乎是在xml文件中未正确声明某些内容。我认为问题是我在xml文件中遗漏了一些东西,但我不知道是什么,我无法在线找到解决方案。

任何人都可以看到我失踪的东西,或者我做错了什么吗?

主要错误似乎是:

android.view.InflateException: Binary XML file line #12: Error inflating class
Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.lang.NullPointerException

xml第12行(&#13):

<oaa.tms.zoneball.ballHold.BallHoldView
android:id="@+id/ballHold"

空指针位于BallHoldView.java:37,即:

scoreText.setText("New Score"); // java line 37.

这是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
}
}

这里是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>

这里是日志猫(错误):

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

编辑: 使用以下代码我已确认scoreText为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");

为什么它为空?

1 个答案:

答案 0 :(得分:0)

问题是您的代码在第37行

scoreText.setText("New Score");

scoreTextnull

scoreText = (TextView)((Activity)getContext()).findViewById(R.id.scoreText);

以上行无法找到scoreText。这可能是因为当自定义视图布局膨胀时,它会调用它的构造函数,并且在那里你试图引用尚未膨胀的scoreText,因为它在你的android中ballHold之后XML。
解决方案可能是将ballHold自定义视图放在android {xml}中的scoreText之后。或者正确的方法是将scoreText TextView从您的java活动代码传递到其构造函数中的BallHoldView CustomView类,然后使用它。在这种情况下,在您的活动代码中,您一定能够通过id找到视图。