0

我决定使用简单的循环而不是硬编码来优化我的代码,因为之前我分别实现了每个 PickView 并且效果很好。

这是一个有问题的地方:

pick = new PickView[9];
int id;
for(int i = 0; i < pick.length; i++) {
    id = getResources().getIdentifier("pick_" + i, "id", getPackageName());
    pick[i] = (PickView)findViewById(id);
    pick[i].setOnTouchListener(this); //this is MainActivity, line:54
}

...我意外地收到了 NullPointerException:

ERROR/AndroidRuntime(8450): FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.***}: java.lang.NullPointerException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.NullPointerException
    at com.***.onCreate(MainActivity.java:54)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
    ... 11 more

我附上了一个 PickView 类:

public class PickView extends RelativeLayout {

    private TextView textView;
    private ImageView imageView;
    private String text;

    public PickView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PickView);
        text = a.getString(R.styleable.PickView_text);

        LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = layoutInflater.inflate(R.layout.pick_view, this);
        textView = (TextView)findViewById(R.id.pick_text);
        imageView = (ImageView)findViewById(R.id.pick_bg);
    }

    public void setText(String text) {
        textView.setText(text);
    }

    public void activate(boolean isActive) {
        if (isActive)
            imageView.setImageResource(R.drawable.pick_active);
        else
            imageView.setImageResource(R.drawable.pick);
    }
}

我将不胜感激任何帮助!

4

3 回答 3

1

Java doc ofgetIdentifier建议0如果没有找到它会返回这是您的问题的原因。所以如果没有找到就findViewById返回。null

public int getIdentifier (String name, String defType, String defPackage)

返回给定资源名称的资源标识符。完全限定的资源名称的格式为“package:type/entry”。如果此处分别指定了 defType 和 defPackage,则前两个组件(包和类型)是可选的。

注意:不鼓励使用此功能。按标识符检索资源比按名称检索资源效率更高。

int The associated resource identifier. Returns 0 if no such resource was found. (0 is not a valid resource ID.)

于 2012-09-06T13:25:07.003 回答
1

只是一个小问题,您有 pick_0 资源吗?

无论如何,您应该检查您是否确实获得了一个 id 并且返回的 PickView 不为空?

于 2012-09-06T13:25:38.127 回答
1

也许你可以这样找到它:

for (int i = 0; i < pick.length; i++)
{
  resources = getResources();
  if(resources == null)
  {
    System.out.println("oops.. no resources");
    throw new RuntimeException("oops... no resources");
  }
  id = resources.getIdentifier("pick_" + i, "id", getPackageName());
  pickView = (PickView) findViewById(id);
  if(resources == null)
  {
    System.out.println("oops.. noo pickView");
    throw new RuntimeException("oops... no pickView");
  }
  pick[i] = pickView;
  pick[i].setOnTouchListener(this); //this is MainActivity, line:54
}
于 2012-09-06T13:32:57.060 回答