我创建了一个带有片段页面适配器的viewpager,其中有两个片段。在我的一个片段中,我在帧布局中显示相机实时预览,但问题是,每当我从第一页滑动到相机预览页面时,它都会延迟。因此,当我向右滑动时,第一个片段和相机预览片段之间出现黑条,因为相机的帧布局不能正确滑动。但这只发生在我正在显示相机实时预览时。如果我要删除预览并将背景颜色设置为绿色,则不会有任何延迟。 相机碎片:
public class CameraFragment extends Fragment {
private Context mContext;
private Camera mCamera;
private CameraPreview mCameraPreview;
private FrameLayout frameLayout;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.camera_layout, container, false);
mContext = getActivity();
frameLayout = (FrameLayout) v.findViewById(R.id.camera_preview);
new Thread() {
public void run() {
Looper.prepare();
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(mContext, mCamera, frameLayout);
try {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
frameLayout.addView(mCameraPreview);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
return v;
}
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = getFrontFacingCamera();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
private Camera getFrontFacingCamera() {
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
try {
cam = Camera.open(camIdx);
} catch (RuntimeException e) {
Log.e("CameraFragment", "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onPause() {
super.onPause();
releaseCamera();
}
private void releaseCamera() {
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
相机预览课程:
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private String TAG = CameraPreview.class.getSimpleName();
private Context mContext;
private FrameLayout frameLayout;
private List<Camera.Size> mSupportedPreviewSizes;
private Camera.Size mPreviewSize;
boolean done = false;
public CameraPreview(Context context, Camera camera, FrameLayout frameLayout) {
super(context);
mContext = context;
mCamera = camera;
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
for (Camera.Size str : mSupportedPreviewSizes)
Log.e(TAG, str.width + "/" + str.height);
this.frameLayout = frameLayout;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
try {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(mPreviewSize.height, mPreviewSize.width);
mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
if (mSupportedPreviewSizes != null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height, true);
if (mPreviewSize == null) {
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height, false);
}
}
float ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
if ((int) (width * ratio) >= height) {
setMeasuredDimension(width, (int) (width * ratio));
} else {
setMeasuredDimension(width, height);
}
done = true;
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h, boolean minSize) {
if (sizes == null) {
return null;
}
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
double frameRatio = (double) h / w;
double testRatio;
int width, height;
for (Camera.Size size : sizes) {
width = size.height;
height = size.width;
if (width > height) {
int t_width = width;
width = height;
height = t_width;
}
if (height < h / 2 && minSize) continue;
testRatio = (double) height / width;
if (Math.abs(frameRatio - testRatio) < minDiff) {
if (optimalSize == null) optimalSize = sizes.get(0);
// else if (frameRatio - testRatio <= 0 && optimalSize.height > height) continue;
optimalSize.width = width;
optimalSize.height = height;
minDiff = Math.abs(frameRatio - testRatio);
Log.d("", "" + frameRatio + ", " + testRatio);
} else if (Math.abs(frameRatio - testRatio) == minDiff) {
if (optimalSize.height > height) continue;
if (optimalSize == null) optimalSize = sizes.get(0);
optimalSize.width = width;
optimalSize.height = height;
minDiff = Math.abs(frameRatio - testRatio);
Log.d("", "" + frameRatio + ", " + testRatio);
}
}
Log.d("", "" + optimalSize.width + ", " + optimalSize.height);
return optimalSize;
}
}
这有点难以解释,但我希望你了解发生了什么。谢谢!