我正在尝试将绘图叠加在相机预览之上。我制作了两个从 SurfaceView 扩展的自定义类:一个用于叠加层,一个用于凸轮。这是我的 logcat(只有“由”语句):
04-11 19:58:06.549: W/dalvikvm(867): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
04-11 19:58:06.609: E/AndroidRuntime(867): Caused by: android.view.InflateException: Binary XML file line #5: Error inflating class com.example.gui_v9.Activity1.CamView
04-11 19:58:06.609: E/AndroidRuntime(867): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.gui_v9.Activity1.CamView" on path: /data/app/com.example.gui_v9-2.apk
它找不到类的第二个错误是因为它没有膨胀。
Eclipse Graphical Layout 成功编译了 xml 代码并提供了不错的预览。这是我的 XML 代码:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.example.gui_v9.Activity1.CamView
android:id="@+id/camview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<com.example.gui_v9.Activity1.OverlayView
android:id="@+id/overlay"
android:layout_width="200dp"
android:layout_height="200dp"/>
</FrameLayout>
我试图从
<com.example.gui_v9.Activity1.OverlayView .../>
至
<com.example.gui_v9.Activity1.OverlayView ...></com.example.gui_v9.Activity1.OverlayView>
或者
<SurfaceView class="com.example.gui_v9.Activity1$OverlayView" ... />
甚至
<SurfaceView class="com.example.gui_v9.Activity1$OverlayView" ... ></SurfaceView>
没有运气。在后一种情况下,我有一个转换问题(CamView 不能在 SurfaceView 中转换)并且 Eclipse 的 XML 图形布局无法呈现,所以我猜第一个在编译过程中让我走得更远。
你也可以看看我的主要活动:
package com.example.gui_v9;
import java.io.IOException;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.hardware.Camera;
public class Activity1 extends Activity {
CamView camview = null;
OverlayView overlay = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity1);
camview = (CamView) findViewById(R.id.camview);
overlay = (OverlayView) findViewById(R.id.overlay);
overlay.getHolder().setFormat(PixelFormat.TRANSLUCENT);
}
public static class CamView extends SurfaceView implements SurfaceHolder.Callback {
Camera cam = null;
SurfaceHolder camviewholder = null;
public CamView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public CamView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public CamView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
if (cam!=null) {
try {
cam.setPreviewDisplay(camviewholder);
}
catch (IOException e) {
}
cam.startPreview();
}
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
cam = Camera.open();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
cam.stopPreview();
cam.release();
}
}
public static class OverlayView extends SurfaceView implements SurfaceHolder.Callback {
private Paint paint = new Paint();
OverlayThread overlaythread = null;
public OverlayView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public OverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public OverlayView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLUE);
canvas.drawCircle(100, 100, 100, paint);
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder arg0) {
setWillNotDraw(false); //Allows us to use invalidate() to call onDraw()
overlaythread = new OverlayThread(getHolder(), this);
overlaythread.setRunning(true);
overlaythread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
try {
overlaythread.setRunning(false);
overlaythread.join();
}
catch (InterruptedException e) {
}
}
}
public static class OverlayThread extends Thread {
private OverlayView overlay;
private SurfaceHolder overlayholder;
private boolean _run = false;
public OverlayThread(SurfaceHolder _overlayholder, OverlayView _overlay) {
overlayholder = _overlayholder;
overlay = _overlay;
}
public void setRunning(boolean run) {
_run = run;
}
@Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = overlayholder.lockCanvas(null);
synchronized (overlayholder) {
overlay.invalidate();
}
}
finally {
if (c != null) {
overlayholder.unlockCanvasAndPost(c);
}
}
}
}
}
}
如您所见,我为每个类(带有 1,2 和 3 个参数)设置了三个构造函数,这是夸大类失败的常见错误。
当我分别在两个单独的类(CamView.java 和 OverlayView.java)中实现 CamView 和 OverlayView 时,我得到了这个工作。所以我不明白为什么导入类使它起作用。也许与静态工作区有关?
谢谢你们的帮助!