我创建了一个Surfaceview来显示我的相机预览。我正在使用onMeasure()函数在运行时设置表面视图宽度和高度。
如果我从我的onMeasure()函数中评论“setLayoutParams(lp)”,那么我的表面视图就会被创建并显示相机预览。但它不合适,因为表面宽度和高度不合适能够保持相机预览的宽高比。由于预览看起来有点拉长。为了避免拉伸我正在计算纵横比并且基于纵横比我设置了surfaceview的宽度和高度。这样它就可以显示正确的相机预览。
第一次调用surfaceCreated函数。由于我已经实现了相机切换功能,因此当我切换相机时,会调用surfaceCreated函数,之后它可以正常工作。
您能否告诉我“setLayoutParams(lp)”如何影响Surfaceview的创建?
注意: - 我正在将相机预览对象添加到FrameLayout。这是我片段布局的一部分。
以下是我的CameraPreview课程。
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
String TAG = getClass().getSimpleName();
private SurfaceHolder mHolder;
private Camera mCamera;
Double aspectRatio;
Context context;
public CameraPreview(Context context) {
super(context);
Log.d(TAG, " CameraPreview constructor");
this.context = context;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setBackgroundDrawable(getResources().getDrawable(R.drawable.face_capture_layout_border));
}
/**
* Extract supported preview and flash modes from the camera.
*
* @param camera
*/
public void setCamera(Camera camera) {
mCamera = camera;
Camera.Parameters params = mCamera.getParameters();
Camera.Size pictureSize = getLargestPictureSize(params);
params.setPictureSize(pictureSize.width, pictureSize.height);
aspectRatio = new Double((float) pictureSize.width / pictureSize.height);
mCamera.setParameters(params);
requestLayout();
}
private Camera.Size getLargestPictureSize(Camera.Parameters params) {
Camera.Size bestSize = null;
List<Camera.Size> sizeList = params.getSupportedPictureSizes();
bestSize = sizeList.get(0);
for (int i = 1; i < sizeList.size(); i++) {
if ((sizeList.get(i).width * sizeList.get(i).height) >
(bestSize.width * bestSize.height)) {
bestSize = sizeList.get(i);
}
}
return bestSize;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, " Surface created");
Surface surface = getHolder().getSurface();
Log.d(TAG, "Surface is in created valid =>" + surface.isValid());
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
Log.d(TAG, " Surface destroyed");
// Surface will be destroyed when we return, so stop the preview.
}
void startCameraPreview() {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
}
catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
}
catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.d(TAG, " Surface changed");
startCameraPreview();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d(TAG, "On measure");
//Parent frame size
View parent = (View) getParent();
int width = parent.getWidth();
int height = parent.getHeight();
int surfaceViewWidth = (int) (height / aspectRatio);
int surfaceViewHeight = (int) (height);
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(surfaceViewWidth, surfaceViewHeight);
lp.gravity = Gravity.CENTER;
setLayoutParams(lp);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}