Масштабирование макета и холста, сопоставление размера с доступным пространством после включения и выключения полноэкранного режима - PullRequest
0 голосов
/ 26 сентября 2018

Я хочу создать приложение для камеры с полноэкранным переходом и масштабированием предварительного просмотра камеры с соотношением сторон, поддерживаемым камерой устройства.

Код, который я использую для создания полноэкранного состояния включения / выключения, равен

   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 на эмуляторе, который имеет полноэкранную ширину 1280 пикселей и высоту: 720 пикселей, с шириной панели навигации 1184.

Когда я переключаюсьиз полноэкранного режима выключен, если SurfaceView внутри ArView не масштабирован. FrameLayout и SurfaceView в нем масштабированы правильно, если я масштабирую 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 и отображения wih реальные метрики всегда возвращают 1280x768

FullScreen изображение без масштабирования

Fullscreen with no scaling

Изображение с NavigationBar без масштабирования

Image with NavigationBar with no Scaling

Изображение с панелью навигации после масштабирования, на этом изображении некоторая часть изображения находится ниже панели навигации

Image with NavigationBar after Scaling

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...