0

我正在尝试引用将 SurfaceView 扩展到 XML 布局的 Main.class。XML是这样的:

<AbsoluteLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>
    <coba.gesture.Main
        android:id="@+id/LayoDalam"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
    />
</AbsoluteLayout>

但是当我运行它时会出错。这是错误:

05-29 11:57:05.713: ERROR/AndroidRuntime(806): FATAL EXCEPTION: main
05-29 11:57:05.713: ERROR/AndroidRuntime(806): java.lang.RuntimeException: Unable to start activity ComponentInfo{coba.gesture/coba.gesture.CobaGesture}: android.view.InflateException: Binary XML file line #47: Error inflating class coba.gesture.MainBaby
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1622)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1638)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:928)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.os.Looper.loop(Looper.java:123)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.ActivityThread.main(ActivityThread.java:3647)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at java.lang.reflect.Method.invokeNative(Native Method)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at java.lang.reflect.Method.invoke(Method.java:507)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at dalvik.system.NativeStart.main(Native Method)
05-29 11:57:05.713: ERROR/AndroidRuntime(806): Caused by: android.view.InflateException: Binary XML file line #47: Error inflating class coba.gesture.MainBaby
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.createView(LayoutInflater.java:508)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:570)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:207)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.Activity.setContentView(Activity.java:1657)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at coba.gesture.CobaGesture.onCreate(CobaGesture.java:19)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1586)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     ... 11 more
05-29 11:57:05.713: ERROR/AndroidRuntime(806): Caused by: java.lang.NoSuchMethodException: MainBaby(Context,AttributeSet)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at java.lang.Class.getMatchingConstructor(Class.java:643)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at java.lang.Class.getConstructor(Class.java:472)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     at android.view.LayoutInflater.createView(LayoutInflater.java:480)
05-29 11:57:05.713: ERROR/AndroidRuntime(806):     ... 22 more

我的预测是错误来自 MainBaby.java 但我不知道出了什么问题。

更新。

这是你想要的 MainBaby.java 的源代码。

public class MainBaby extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = MainBaby.class.getSimpleName();
private ObjBaby obaby;
private ThreadBaby thread;
private static final float TOUCH_TOLERANCE = 4;

static float static_x = 0;
static float static_y = 0;
float mX, mY;
Paint p;
Path mPath;
Canvas mCanvas;
Bitmap mBitmap;
Paint mBitmapPaint;


public MainBaby(Context context){
    super(context);


    // adding the callback (this) to the surface holder to intercept events

    getHolder().addCallback(this);

    obaby = new ObjBaby(BitmapFactory.decodeResource(getResources(), R.drawable.clue_btn), 50, 50);

    // create the game loop thread
    thread = new ThreadBaby(getHolder(), this);

    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    p = new Paint();
     p.setAntiAlias(true);
     p.setDither(true);
     p.setColor(Color.WHITE);
     p.setStyle(Paint.Style.STROKE);
     p.setStrokeJoin(Paint.Join.ROUND);
     p.setStrokeCap(Paint.Cap.ROUND);
     p.setStrokeWidth(12);



    setFocusable(true);

}



@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    thread.setRunning(true);
    thread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    boolean retry = true;
    while (retry) {
        try {
            thread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        retry = false;
    }
}

private void touch_start(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
}

private void touch_move(float x, float y) {
    float dx = Math.abs(x - mX);
    float dy = Math.abs(y - mY);
    if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
        mX = x;
        mY = y;
    }
}

private void touch_up() {
    mPath.lineTo(mX, mY);
    // commit the path to our offscreen
    mCanvas.drawPath(mPath, p);

    // kill this so we don't double draw
    mPath.reset();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    static_x = event.getX();
    static_y = event.getY();

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        // delegating event handling to the droid
        obaby.handleActionDown((int)event.getX(), (int)event.getY());
        touch_start(static_x, static_y);



        if (event.getY() > getHeight() - 50) {
            thread.setRunning(false);
            ((Activity)getContext()).finish();
        } else {
            //Log.d(TAG, "Coords: x=" + event.getX() + ",y=" + event.getY());
        }
    } if (event.getAction() == MotionEvent.ACTION_MOVE) {
        // the gestures
        if (obaby.isTouched()) {
            // the droid was picked up and is being dragged
            obaby.setX((int)event.getX());
            obaby.setY((int)event.getY());
            touch_move(static_x, static_y);
        }
    } if (event.getAction() == MotionEvent.ACTION_UP) {
        // touch was released
        if (obaby.isTouched()) {
            touch_up();
            obaby.setTouched(false);


        }
    }
    return true;
}

@Override
protected void onDraw(Canvas canvas) {
    // fills the canvas with black
    canvas.drawColor(Color.BLACK);



    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    canvas.drawPath(mPath, p);
    obaby.draw(canvas);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    //mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.background_number);
    mCanvas = new Canvas(mBitmap);

}
}
4

1 回答 1

1

当您像这样扩展视图类型并在 XML 中创建实例时,Android 会在后台调用MainBaby(Context context, AttributeSet attrs)其中 AttributeSet 是您在 XML 中定义的所有内容。但是您只覆盖了MainBaby(Context context),因此要修复此错误,请从这里开始:

public MainBaby(Context context){
    super(context);
    ...

并通过尝试以下方法覆盖您的所有基础:

public MainBaby(Context context) {
    super(context);
    init();
}

public MainBaby(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public MainBaby(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

private void init() {
    // Original constructor code here
    ...

新方法init()应该包含来自您的第一个构造函数的初始化代码。

另外,我可能遗漏了未包含的代码中的某些内容,但您是否要MainBaby在此处引用您的视图?

<coba.gesture.Main
    android:id="@+id/LayoDalam"
    ...

如果是这样,我认为您的意思是:

<coba.gesture.MainBaby
    android:id="@+id/LayoDalam"
    ...

最后,AbsoluteLayout 已被弃用,因为它们不容易跨不同密度的屏幕移植。这来自开发人员指南

3.不要使用AbsoluteLayout

与其他布局小部件不同,AbsoluteLayout 强制使用固定位置来布置其子视图,这很容易导致用户界面在不同的显示器上无法正常工作。因此,AbsoluteLayout 在 Android 1.5(API 级别 3)中已被弃用。

您应该改用RelativeLayout,它使用相对定位来布置其子视图。例如,您可以指定按钮小部件应出现在文本小部件的“右侧”。

于 2012-05-29T07:36:57.867 回答