如何在XML布局中使用扩展类?

时间:2015-08-06 21:21:09

标签: android android-layout android-camera surfaceview

我为相机预览创建了一个扩展的SurfaceView类。

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;

    CameraPreview(Context context) {
        super(context);

        mHolder = this.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.
        try {
            mCamera = Camera.open();
            mCamera.setPreviewDisplay(holder);
        } catch (Exception e){
            Log.wtf("surfaceCreated", e.toString());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        try {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        } catch (Exception e){
            Log.wtf("surfaceDestroyed", e.toString());
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        try {
            Camera.Parameters parameters = mCamera.getParameters();
            // parameters.setPreviewSize(w, h);
            // parameters.setPreviewSize(222, 222);
            mCamera.setParameters(parameters);
            mCamera.startPreview();
        } catch (Exception e){
            Log.wtf("surfaceChanged", e.toString());
        }
    }
}

在以下活动中使用时,它可用作全屏预览:

public class CameraActivity extends Activity {
    CameraPreview mPreview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE); 
        mPreview = new CameraPreview(this);
        setContentView(mPreview);
    }
}

当我尝试在XML布局文件中使用它时,它会产生ClassNotFoundException。

<CameraPreview class="com.xxxxxx.camera3.CameraPreview"
    android:layout_width="260dp"
    android:layout_height="260dp"
    android:id="@+id/surfaceView"
    android:background="#ff404040"
    android:layout_gravity="center_horizontal"/> 

我需要做些什么才能让它发挥作用? 如何在SurfaceView中放置相机预览?

1 个答案:

答案 0 :(得分:5)

说出包含新视图的包名称为: com.ranandar.views

在xml中执行以下操作:

<com.ranandar.views.CameraPreview
    android:layout_width="260dp"
    android:layout_height="260dp"
    android:id="@+id/surfaceView"
    android:background="#ff404040"
    android:layout_gravity="center_horizontal"/> 

在包 com.ranandar.views 中查找,找到定义该视图的类,并使用它。

您的活动中存在问题。您正在将内容视图设置为该表面视图,这是不对的。

编辑:添加您请求的示例。

public class CameraPreview extends SurfaceView implements   SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;

    CameraPreview(Context context) {
        super(context);
        init();
    }

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

    public void init(){
        mHolder = this.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    //additionally with all your other code
    ...
}

所以我所做的就是添加定义自定义视图所需的构造函数,并在XML中使用它。您需要定义其他构造函数,以便在XML中使用它时,属性集将传递给视图。属性集是您声明的各种字段,如layout_width / height,background等。否则,如果没有此构造函数,CameraPreview将无法通过传递没有构造函数的属性集来处理它。双参数构造函数super(context,attrs)中的调用使用您定义的属性进行处理。

进一步学习可能需要的文档:Creating Custom Views

需要将XML文件的根视图设置为ViewGroup类,如RelativeLayout,LinearLayout等...在这种情况下,请执行框架布局:

 <?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    andorid:layout_height="match_parent">

    <com.ranandar.views.CameraPreview
        android:id="@+id/camera_preview"
        android:layout_width="260dp"
        android:layout_height="260dp"
        android:id="@+id/surfaceView"
        android:background="#ff404040"
        android:layout_gravity="center_horizontal"/> 

</FrameLayout>

假设此xml文件名为activity_main.xml

执行以下操作:

public class CameraActivity extends Activity {
    CameraPreview mPreview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        requestWindowFeature(Window.FEATURE_NO_TITLE); 
        mPreview = (CameraPreview) findViewById(R.id.camera_preview);
    }
}

始终确保首先设置setContentView,然后再调整可能会调用布局组件的任何内容。这可能是您的问题