单击按钮时如何隐藏SurfaceView?

时间:2017-10-05 05:33:38

标签: android camera surfaceview

我想做的是,在SurfaceView打开相机的活动中,并在其中进行预览。点击一个按钮后,SurfaceView停止/不可见,因此图像捕获将显示在活动中ImageView

如下图所示:

enter image description here

所以我有一个自定义相机活动,其中包含如下所示的XML,

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<SurfaceView
    android:id="@+id/surface_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

<ImageView
    android:id="@+id/showImage"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="invisible" />

<FloatingActionButton
    android:id="@+id/cameraButton"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_centerHorizontal="true" />

</FrameLayout>

我想要做的是,当我点击浮动按钮时,SurfaceView消失,ImageView可见,然后ImageView上显示的相机拍摄的图像。

所以我到目前为止尝试了

 public class CameraActivity extends AppCompatActivity implements 
 SurfaceHolder.Callback {
    Camera mCamera;
    Camera.PictureCallback jpegCallback;

    ImageView showImage;
    FloatingActionButton btnCamera;
    SurfaceHolder surfaceHolder;
    SurfaceView surfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity);

        btnCamera = (FloatingActionButton) findViewById(R.id.cameraButton);
        surfaceView = (SurfaceView)findViewById(R.id.surface_view);
        showImage = (ImageView)findViewById(R.id.showImage);

        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        btnCamera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //here when click the camera button
                //camera take photo
                //surface view disappear
                //preview image shown on image view
                mCamera.takePicture(null,null,jpegCallback);
                showImage.setVisibility(View.VISIBLE);
                surfaceView.setVisibility(View.INVISIBLE);

            }
        });

        jpegCallback = new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                FileOutputStream outputStream = null;
                File file_image = getDirs();

                if(!file_image.exists() && !file_image.mkdirs()){
                    Toast.makeText(getApplicationContext(),"Failed to save picture",Toast.LENGTH_LONG).show();
                }

                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
                String date = simpleDateFormat.format(new Date());
                String photofile = "myphotos" + date+ ".jpg";
                String file_name = file_image.getAbsolutePath() + "/" + photofile;
                File picFile = new File(file_name);
                Bitmap bitmap = null;

                try{
                    outputStream = new FileOutputStream(picFile);
                    outputStream.write(data);
                    outputStream.close();

                    //here set the picture capture to the image view
                    //convert it to bitmap,setBitmap to the imageView
                    bitmap = decodeFile(picFile,10);

                    if(bitmap !=null){
                        showImage.setImageBitmap(bitmap);
                        Toast.makeText(CameraActivity.this,
                                "Picture Captured Successfully:", Toast.LENGTH_LONG)
                                .show();
                    }else {
                        Toast.makeText(CameraActivity.this,
                                "Failed to Capture the picture. kindly Try Again:",
                                Toast.LENGTH_LONG).show();
                    }


                } catch (IOException e){
                    e.printStackTrace();
                }
                Toast.makeText(getApplicationContext(),"Picture saved",Toast.LENGTH_LONG).show();
                refreshCamera();
            }
        };
    }

    private void refreshCamera() {
        if(surfaceHolder.getSurface() == null){
            return;
        }

        //stop the camera preview
        try{
            mCamera.stopPreview();
        }catch (Exception e){
            e.printStackTrace();
        }
        //start camera again
        try{
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //open camera
        try{
            mCamera = Camera.open();
        }catch (RuntimeException ex){
            ex.printStackTrace();
        }

        Camera.Parameters parameters;
        parameters = mCamera.getParameters();
        parameters.setPreviewFrameRate(20);
        parameters.setPreviewSize(352,288);
        mCamera.setParameters(parameters);
        mCamera.setDisplayOrientation(90);

        try{
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        }catch (Exception e){
            e.printStackTrace();
        }


    }

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

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

尝试此操作后,我现在得到的是,屏幕完全空白。SurfaceView是不可见的,ImageView预览从相机中取出的图像未显示出来。 但我检查了file_namebitmap在日志中有值。

所以我尝试过,不要将SurfaceView设置为隐身,如下所示:

btnCamera.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            cameraImage();
            showImage.setVisibility(View.VISIBLE);
            //surfaceView.setVisibility(View.INVISIBLE);

        }
    });

图像可以显示在表面视图的顶部,如下所示,但如果我将表面视图设置为不可见,则整个屏幕显示为空白。

enter image description here

但我希望表面视图消失,只有ImageView可用。

1 个答案:

答案 0 :(得分:0)

移动以下行(使表面视图不可见),

surfaceView.setVisibility(View.INVISIBLE);

onClick(View v)方法到onPictureTaken(byte[] data, Camera camera)方法可以解决问题。

但是,这会导致相机release,并且必须再次打开以拍摄另一张照片。