简体   繁体   中英

Error using Canvas to draw simple shapes and cursor coordinates with OnTouchListener

I am working on a test program that utilized the Canvas onDraw method to draw basic line/shapes and dispense the coordinates of touch event with the onTouch method. Whenever I run the program, it would show an error message of "The application has stopped unexpectedly. Please try again."

Any insight to resolv this problem is very much appreciated!

public class CustomDraw extends Activity implements OnTouchListener{
    StringBuilder builder = new StringBuilder();
    String text;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                             WindowManager.LayoutParams.FLAG_FULLSCREEN);
        RenderView rv = new RenderView(this);
        rv.setOnTouchListener(this);
        setContentView(rv);

    }
    class RenderView extends View {        
        Paint paint;

    public RenderView(Context context) {
        super(context);
        paint = new Paint();            
    }

    protected void onDraw(Canvas canvas) {
        canvas.drawRGB(255, 255, 255);            
        paint.setColor(Color.RED);
        canvas.drawLine(0, 0, canvas.getWidth()-1, canvas.getHeight()-1, paint);

        paint.setStyle(Style.STROKE);
        paint.setColor(0xff00ff00);            
        canvas.drawCircle(canvas.getWidth() / 2, canvas.getHeight() / 2, 40, paint);

        paint.setStyle(Style.FILL);
        paint.setColor(0x770000ff);
        canvas.drawRect(100, 100, 200, 200, paint);

        paint.setStyle(Style.FILL);
        paint.setColor(Color.BLACK);
        canvas.drawText(text, 10, 25, paint);

        invalidate();
    }
}

    public boolean onTouch(View v, MotionEvent event) {

        builder.setLength(0);
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            builder.append("down, ");
            break;
        case MotionEvent.ACTION_MOVE:
            builder.append("move, ");
            break;
        case MotionEvent.ACTION_CANCEL:
            builder.append("cancle, ");
            break;
        case MotionEvent.ACTION_UP:
            builder.append("up, ");
            break;
        }

        builder.append(event.getX());
        builder.append(", ");
        builder.append(event.getY());
        text = builder.toString();
        Log.d("TouchTest", text);

        return true;
    }
}

As requested, here's the log result.

07-06 01:08:10.520: W/KeyCharacterMap(367): No keyboard for id 0
07-06 01:08:10.520: W/KeyCharacterMap(367): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
07-06 01:08:12.391: D/AndroidRuntime(367): Shutting down VM
07-06 01:08:12.391: W/dalvikvm(367): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
07-06 01:08:12.401: E/AndroidRuntime(367): Uncaught handler: thread main exiting due to uncaught exception
07-06 01:08:12.411: E/AndroidRuntime(367): java.lang.NullPointerException
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.graphics.Canvas.drawText(Native Method)
07-06 01:08:12.411: E/AndroidRuntime(367):  at com.badlogic.androidgames.CustomDraw$RenderView.onDraw(CustomDraw.java:72)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.View.draw(View.java:6535)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.View.draw(View.java:6538)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.widget.FrameLayout.draw(FrameLayout.java:352)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.View.draw(View.java:6538)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.widget.FrameLayout.draw(FrameLayout.java:352)
07-06 01:08:12.411: E/AndroidRuntime(367):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.ViewRoot.draw(ViewRoot.java:1349)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1114)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.os.Handler.dispatchMessage(Handler.java:99)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.os.Looper.loop(Looper.java:123)
07-06 01:08:12.411: E/AndroidRuntime(367):  at android.app.ActivityThread.main(ActivityThread.java:4363)
07-06 01:08:12.411: E/AndroidRuntime(367):  at java.lang.reflect.Method.invokeNative(Native Method)
07-06 01:08:12.411: E/AndroidRuntime(367):  at java.lang.reflect.Method.invoke(Method.java:521)
07-06 01:08:12.411: E/AndroidRuntime(367):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
07-06 01:08:12.411: E/AndroidRuntime(367):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
07-06 01:08:12.411: E/AndroidRuntime(367):  at dalvik.system.NativeStart.main(Native Method)
07-06 01:08:12.421: I/dalvikvm(367): threadid=7: reacting to signal 3
07-06 01:08:12.421: I/dalvikvm(367): Wrote stack trace to '/data/anr/traces.txt'
07-06 01:08:17.540: I/Process(367): Sending signal. PID: 367 SIG: 9

You need to set this statement into down case when you touch first time. currently it will continue set reset length for your builder in onTouch

builder.setLength(0);

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        builder.setLength(0);
        builder.append("down, ");
        break;

When application is started.

Your String text is not set yet and in your onDraw you have this

  canvas.drawText(text, 10, 25, paint);

This causes NullPointerException

From

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/graphics/Canvas.java#Canvas.0mNativeCanvas

1275    public void drawText(String text, int start, int end, float x, float y,
1276                         Paint paint) {
1277        if ((start | end | (end - start) | (text.length() - end)) < 0) {
1278            throw new IndexOutOfBoundsException();
1279        }
1280        native_drawText(mNativeCanvas, text, start, end, x, y,
1281                        paint.mNativePaint);
1282    }

So just initialise your text at the start

String text="initial";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM