<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1">

        <com.myproject.test.Preview android:id="@+id/preview"   <--- 제가 만든 Preview 클래스
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        <LinearLayout android:id="@+id/hidecontainer"
                android:orientation="vertical"
                android:visibility="invisible"
                android:background="@drawable/translucent_background"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

            <Button android:id="@+id/hideme1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:visibility="gone"
                    android:text="aa"/>
           
            <Button android:id="@+id/hideme2"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:visibility="gone"
                    android:text="bb"/>
                   
        </LinearLayout>
       
    </FrameLayout>
           
    <LinearLayout
            android:orientation="horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center">

        <Button android:id="@+id/vis"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="cc"/>

        <Button android:id="@+id/invis"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="dd"/>

        <Button android:id="@+id/gone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="ee"/>

    </LinearLayout>

</LinearLayout>




여기까지 XML 레이아웃의 내용이구요..

프레임레이아웃을 이용했습니다.



public class TestPreview extends Activity {
    View mVictimContainer;
    View mVictim1;
    View mVictim2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState); 
        setContentView(R.layout.testpreview);        

        Preview mPreview = new Preview(findViewById(R.id.preview).getContext()); //디버그하면 여기서 걸립니다.
               

        
        // Find the views whose visibility will change
        mVictimContainer = findViewById(R.id.hidecontainer);
        mVictim1 = findViewById(R.id.hideme1);
        mVictim1.setOnClickListener(new HideMeListener(mVictim1));
        mVictim2 = findViewById(R.id.hideme2);
        mVictim2.setOnClickListener(new HideMeListener(mVictim2));

        // Find our buttons
        Button visibleButton = (Button) findViewById(R.id.vis);
        Button invisibleButton = (Button) findViewById(R.id.invis);
        Button goneButton = (Button) findViewById(R.id.gone);

        // Wire each button to a click listener
        visibleButton.setOnClickListener(mVisibleListener);
        invisibleButton.setOnClickListener(mInvisibleListener);
        goneButton.setOnClickListener(mGoneListener);
    }

    @Override
    protected void onResume() {
        // Ideally a game should implement onResume() and onPause()
        // to take appropriate action when the activity looses focus
        super.onResume();
    }

    @Override
    protected void onPause() {
        // Ideally a game should implement onResume() and onPause()
        // to take appropriate action when the activity looses focus
        super.onPause();
    }

    class HideMeListener implements OnClickListener {
        final View mTarget;

        HideMeListener(View target) {
            mTarget = target;
        }

        public void onClick(View v) {
            mTarget.setVisibility(View.INVISIBLE);
        }

    }

    OnClickListener mVisibleListener = new OnClickListener() {
        public void onClick(View v) {
            mVictim1.setVisibility(View.VISIBLE);
            mVictim2.setVisibility(View.VISIBLE);
            mVictimContainer.setVisibility(View.VISIBLE);
        }
    };

    OnClickListener mInvisibleListener = new OnClickListener() {
        public void onClick(View v) {
            mVictim1.setVisibility(View.INVISIBLE);
            mVictim2.setVisibility(View.INVISIBLE);
            mVictimContainer.setVisibility(View.INVISIBLE);
        }
    };

    OnClickListener mGoneListener = new OnClickListener() {
        public void onClick(View v) {
            mVictim1.setVisibility(View.GONE);
            mVictim2.setVisibility(View.GONE);
            mVictimContainer.setVisibility(View.GONE);
        }
    };
}

 

 

 


class Preview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;
   
    Preview(Context context) {
        super(context);

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


    public void surfaceCreated(SurfaceHolder holder) {
       
        mCamera = Camera.open();
        try {
           mCamera.setPreviewDisplay(holder);
        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
    
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }


    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.05;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
       Camera.Parameters parameters = mCamera.getParameters();

        List<Size> sizes = parameters.getSupportedPreviewSizes();
        Size optimalSize = getOptimalPreviewSize(sizes, w, h);
        parameters.setPreviewSize(optimalSize.width, optimalSize.height);

        mCamera.setParameters(parameters);
        mCamera.startPreview();
   
    }

}


여기까지 소스 내용입니다. 카메라 프리뷰위에 레이아웃을 띄워서 버튼을 올리려는거구요.

Preview mPreview = new Preview(findViewById(R.id.preview).getContext()); 에서 에러가 나는거같은데.. 이유를 모르겠군요

디버그를 해보면 SDK의 ActivityThread 클래스의 performLaunchActivity 메소드에서 InflateException이 발생합니다.

detailMessage 를 확인해보면 Binary XML file line #15: Error inflating class com.myproject.test.Preview 라고 나옵니다.


안드로이드 SDK 샘플 ApiDemo에 SurfaceViewOverlay 를 참고해 만들었습니다.

답답해 죽겠습니다. 하다하다 안되서 질문올립니다.