Question

I'm attempting to create a custom SurfaceView that will be used draw a menu/or other components on top of another SurfaceView that is currently display the Camera’s live output.

Therefore I created a Class “OverlayOfSurfaceView” that extends SurfaceView , see below:

  package com.net.app.barcode;

    import com.net.app.R;

    import android.content.Context;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;

    public class OverlayOfSurfaceView extends SurfaceView  implements
SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Context context;
    private LinearLayout linearMenu = null; 
    public OverlayOfSurfaceView(Context context, AttributeSet attr) {
        super(context,attr);
        this.context = context;
        // TODO Auto-generated constructor stub
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        linearMenu = (LinearLayout) this.findViewById(R.layout.barcode_scanner_overlay_menu);
        setFocusable(true);
        requestFocus();


    }


    @Override
    public void onDraw(Canvas canvas) {

    drawGuidance(canvas);
    }

    public void drawGuidance(Canvas canvas) {

         Log.w(this.getClass().getName(),"drawGuidance(Canvas canvas)");
        Paint paintRed = new Paint();
        paintRed.setStyle(Paint.Style.STROKE);
        paintRed.setStrokeWidth(6f);
        paintRed.setAntiAlias(true);
        paintRed.setColor(Color.BLUE);
        // drawMiddleline
        canvas.drawLine( this.getHeight()/2,0,this.getWidth(),this.getHeight()/2 , paintRed);

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
         Log.w(this.getClass().getName(),"surface created");
        // TODO Auto-generated method stub
        setWillNotDraw(false);

    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
         Log.w(this.getClass().getName(),"surface changed");
        // TODO Auto-generated method stub
        // If your preview can change or rotate, take care of those events
                    // here.
    }



    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
         Log.w(this.getClass().getName(),"surface destroyed");
        // TODO Auto-generated method stub
        // empty. Take care of releasing resources here 
    }

}//end class

The layout of OverlayOfSurfaceView, see below:

   <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/LayoutForPreview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:screenOrientation="portrait"
    android:scaleType="fitXY" >


     <SurfaceView
        android:id="@+id/surfaceViewBarcodeScanner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
         />

     <com.yourmarketnet.yourmarketapp.barcode.OverlayOfSurfaceView
        android:id="@+id/overlay"
        android:layout_width="match_parent"
       android:layout_height="wrap_content"
        android:scaleType="fitXY" />


</FrameLayout>

Finally below is the relevant snippet of onCreate() method, in the Activity () were im instantiating the custom SurfaceView called OverlayOfSurfaceView:

  public class ScanVinFromBarcodeActivity extends Activity {

    //irrelevant parts not included in this post

    // onCreate method, instantiates layouts & surfaceView used for video preview
        @Override
            public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_barcode_vin_scanner);
        Log.d("ClassScanViewBarcodeActivity", "onCreate ");

        // create surfaceView for previewing of camera image
        FrameLayoutBarcodeScanner = (FrameLayout) findViewById(R.id.LayoutForPreview);  
        surfaceViewBarcodeScanner = (SurfaceView) findViewById(R.id.surfaceViewBarcodeScanner);

        surfaceViewLayOver = (OverlayOfSurfaceView) findViewById(R.id.overlay);
        //make the background transparent so the user can see surfaceViewBarcodeScanner behind this SurfaceView
        surfaceViewLayOver.setAlpha(0);
        //pass overlay to layout 
        FrameLayoutBarcodeScanner.addView(surfaceViewLayOver);

        globalContext  = this.getApplicationContext();
        initializeGlobalCamera();

//removed code irrelevant to this post 

}//end onCreate


    //irrelevant parts not included in this post
    }//end Activity class

Actual error snippets from logs:

Finally below is the relevant snippet of onCreate() method, in the Activity where I am instantiating the Class: Here is the runtime exception that causes the nasty crash:

04-04 18:05:40.833: E/AndroidRuntime(15123): java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.net.app/com.net.app.barcode.ScanVinFromBarcodeActivity}: 
android.view.InflateException: Binary XML file line #18: 
Error inflating class com.net.app.barcode.OverlayOfSurfaceView
04-04 18:05:40.833: E/AndroidRuntime(15123): Caused by: android.view.InflateException: 
Binary XML file line #18: Error inflating class com.net.app.barcode.OverlayOfSurfaceView

04-04 18:05:40.833: E/AndroidRuntime(15123): 
Caused by: java.lang.NoSuchMethodException: <init> 
[class android.content.Context, interface android.util.AttributeSet]

Please be kind enough to provide working solutions to this problem. Thanks

Was it helpful?

Solution

You need to have certain constructors to be able to instantiate your custom view through XML.

http://developer.android.com/training/custom-views/create-view.html#subclassview

I don't want to provide a working solution though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top