我希望制作一个具有全屏过渡功能并以设备相机支持的纵横比缩放相机预览的相机应用。
我用于创建全屏开/关切换状态的代码是
public void hideSystemUI(boolean isFullScreen) {
if (Build.VERSION.SDK_INT >= 16) {
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_FULLSCREEN;
if (Build.VERSION.SDK_INT >= 19) {
uiOptions = uiOptions | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
if (isFullScreen) {
// hide nav bar
uiOptions = uiOptions | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
decorView.setSystemUiVisibility(uiOptions);
}
}
应用布局
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Main Content -->
<RelativeLayout
android:id="@+id/layout_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F00">
<augmentedreality.view.ARView
android:id="@+id/camera_preview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Navigation Buttons -->
<include
layout="@layout/layout_cam_menu"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
我在模拟器上使用了Nexus 4,该模拟器的全屏宽度为1280px,高度为720px,导航栏宽度为1184。
如果我未从全屏切换到ArView内的SurfaceView进行缩放时,则对FrameLayout进行了正确缩放,并且如果我将SurfacView缩放为小于父级RelativeLayout的尺寸,则RelativeLayout不会得到缩放,并以1280x720和某些部分保持完整尺寸它仍然保留在导航栏下。
将屏幕尺寸设置为字段
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
View parent = ((View) getView().getParent().getParent());
int parentWidth = parent.getWidth();
int parentHeight = parent.getHeight();
mDeviceScreenSize = new Size(parentWidth, parentHeight);
// Set Preview Surface Dimensions
setSize(width, height);
dispatchSurfaceChanged();
Rect rect = holder.getSurfaceFrame();
System.out.println("*****************************");
System.out.println("SurfaceViewPreview surfaceChanged() width: " + width + ", height: " + height);
System.out.println("SurfaceViewPreview surfaceChanged() getWidth(): " + getWidth() + ", getHeight(): " + getHeight());
System.out.println("SurfaceViewPreview surfaceChanged() PARENT width: "
+ ", width: " + parentWidth + ", height: " + parentHeight);
System.out.println("SurfacePreview surfaceChanged() RECT SurfaceFrame WIDTH: "
+ rect.right + ", HEIGHT: " + rect.bottom);
System.out.println("SurfacePreview surfaceChanged() SCREEN width: " + mDeviceScreenSize.width + ", height: " + mDeviceScreenSize.height);
System.out.println("*****************************");
}
相机预览和绘制SurfaceViews的缩放代码
public void setPreviewScreenSize(int cameraPreviewWidth, int cameraPreviewHeight) {
float ratio = (float) cameraPreviewWidth / cameraPreviewHeight;
// These values are scaled SurfaceView dimension depending on aspect ratio
int previewWidth;
int previewHeight;
// Landscape
if (mDeviceScreenSize.width > mDeviceScreenSize.height) {
previewWidth = (int) (mDeviceScreenSize.height * ratio);
previewHeight = mDeviceScreenSize.height;
// Preview width is bigger than screen width
if (previewWidth > mDeviceScreenSize.width) {
System.out.println("SurfacePreview setPreviewScreenSize() WIDTH PREVIEW > SCREEN");
previewWidth = mDeviceScreenSize.width;
previewHeight = (int) (previewWidth / ratio);
}
} else {
// Portrait
previewWidth = mDeviceScreenSize.width;
previewHeight = (int) (mDeviceScreenSize.width * ratio);
// Preview height is bigger than screen height
if (previewHeight > mDeviceScreenSize.height) {
System.out.println("SurfacePreview setPreviewScreenSize() HEIGHT PREVIEW > SCREEN");
previewHeight = mDeviceScreenSize.height;
previewWidth = mDeviceScreenSize.width;
}
}
System.out.println("++++++++++++++++++++++");
System.out.println("SurfacePreview setPreviewScreenSize() Camera Preview cameraPreviewWidth: " + cameraPreviewWidth + ", cameraPreviewHeight: " + cameraPreviewHeight);
System.out.println("SurfacePreview setPreviewScreenSize() Screen width: " + mDeviceScreenSize.width + ", height: " + mDeviceScreenSize.height);
System.out.println("SurfacePreview setPreviewScreenSize() getWidth(): " + getWidth() + ", getHeight(): " + getHeight());
System.out.println("SurfacePreview setPreviewScreenSize() ratio " + ratio + ", previewWidth: "
+ previewWidth + ", previewHeight: " + previewHeight);
System.out.println("++++++++++++++++++++++");
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(previewWidth, previewHeight);
params.gravity = Gravity.CENTER;
mSurfaceView.setLayoutParams(params);
if (mPreviewChangeListener != null)
mPreviewChangeListener.onPreviewSizeChanged(previewWidth, previewHeight);
}
我尝试获取DisplayMetrics的窗口大小,但显示指标始终使用导航栏1184x768返回尺寸,而显示真实指标时始终返回1280x768
不缩放的全屏图像
带有NavigationBar且没有缩放比例的图像
缩放后具有NavigationBar的图像,在此图像中,图像的某些部分位于NavigationBar下方