简体   繁体   English

使用Canvas通过OnTouchListener绘制简单的形状和光标坐标时出错

[英]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. 我正在使用Canvas onDraw方法绘制基本线条/形状并使用onTouch方法分配触摸事件的坐标的测试程序。 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 当前它将继续在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 您的String文本尚未设置,并且在onDraw您有

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

This causes NullPointerException 这导致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 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";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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