在Canvas上绘制listView - setAdapter导致NullPointerException

时间:2013-02-17 11:19:12

标签: android android-listview nullpointerexception

我一直在尝试在Canvas上绘制ListView,当我尝试将适配器设置为该listView时,我得到一个NullPointerException。我检查了一下,看起来listView在初始化后为空,我不明白为什么。

以下是代码:

public class Testing extends Activity {
    MySurface ms;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ms = new MySurface(this);
        setContentView(ms);

        String[] stuffArray = {"stuff1", "stuff2"};
        ListView listView = (ListView) findViewById(R.id.lvListView);   // after this listView is null
        ArrayAdapter<String> listViewAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, stuffArray);

        //listView.setAdapter(listViewAdapter);     // This line crashes program
    }

    @Override
    protected void onResume() {
        super.onResume();
        ms.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        ms.pause();
    }

    public class MySurface extends SurfaceView implements Runnable {
        SurfaceHolder holder;
        Thread t = null;
        volatile boolean isRunning = false;

        public MySurface(Context context) {
            super(context);
            holder = getHolder();
        }

        public void pause(){
            isRunning = false;
            while(true) {
                try {
                    t.join();
                    break;
                } catch (InterruptedException e) { }
            }
        }

        public void resume(){
            isRunning = true;
            t = new Thread(this);
            t.start();
        }

        public void run() {
            LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View v = li.inflate(R.layout.testing, null);
            v.measure(MeasureSpec.getSize(v.getMeasuredWidth()), MeasureSpec.getSize(v.getMeasuredHeight()));
            v.layout(0, 0, 0, 0);

            while(isRunning){
                if(!holder.getSurface().isValid()) continue;

                Canvas canvas = holder.lockCanvas();
                canvas.translate(50, 50);
                v.draw(canvas);

                holder.unlockCanvasAndPost(canvas);
            }
        }
    }
}

test.xml布局的内容:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/tvTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="List of stuff:" />

    <ListView
        android:id="@+id/lvListView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

LogCat窗口抛出:

02-17 12:14:56.359: E/AndroidRuntime(9226): FATAL EXCEPTION: main
02-17 12:14:56.359: E/AndroidRuntime(9226): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testing/com.example.testing.Testing}: java.lang.NullPointerException
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.os.Looper.loop(Looper.java:123)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.app.ActivityThread.main(ActivityThread.java:3687)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at java.lang.reflect.Method.invokeNative(Native Method)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at java.lang.reflect.Method.invoke(Method.java:507)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at dalvik.system.NativeStart.main(Native Method)
02-17 12:14:56.359: E/AndroidRuntime(9226): Caused by: java.lang.NullPointerException
02-17 12:14:56.359: E/AndroidRuntime(9226):     at com.example.testing.Testing.onCreate(Testing.java:30)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-17 12:14:56.359: E/AndroidRuntime(9226):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
02-17 12:14:56.359: E/AndroidRuntime(9226):     ... 11 more
02-17 12:14:56.369: E/(160): Dumpstate > /data/log/dumpstate_app_error

1 个答案:

答案 0 :(得分:0)

好的,我明白了。看来android无法找到R.id.lvListView(在tests.xml中定义)因为tests.xml没有设置为应用程序的View,它只是在Canvas上绘制。这样listView保持为null,当我尝试将适配器设置为它时,抛出了NullPointerException。

我是这样做的:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ms = new MySurface(this);

        RelativeLayout layout = new RelativeLayout(this);
        layout.addView(ms);

        LayoutInflater inflater = LayoutInflater.from(this);
        inflater.inflate(R.layout.testing, layout);
        setContentView(layout);
    }

它顺利运行,我可以使用findViewById()方法获取布局组件。

非常感谢您的承诺!