Android: SurfaceView SurfaceChanged Center в родительском

Я создаю приложение, которое берет изображение и центрирует его на экране для изменения. Я использую SurfaceView и Canvas. Я пытаюсь центрировать SurfaceView в родительском RelativeLayout. У меня было это работает, но оно будет искажаться при повороте. Поэтому в настоящее время я использую метод surfaceChanged для сброса размера растрового изображения и холста при изменении ориентации:

@Override
public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {
    if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        bitmap_width = height * imageRatio;
        bitmap_height = height;
    } else {
        bitmap_width = width;
        bitmap_height = width / imageRatio;
    }

    canvas_width = (int) bitmap_width;
    canvas_height = (int) bitmap_height;

    try {
        canvas_bitmap = Bitmap.createScaledBitmap(initial_bitmap, (int) bitmap_width, (int) bitmap_height, true);
        surface_canvas = new Canvas();
        surface_canvas.setBitmap(canvas_bitmap);
    } catch (Exception exception) {
        exception.printStackTrace();
    }
}

Теперь масштабирование работает, но теперь оно не центрировано. Я также заметил, что остальная часть фона черная, а не серая, как раньше. Это привело бы меня к мысли, что холст простирается за пределы растрового изображения. При дальнейшей проверке я заметил, что метод surfaceChanged вызывается дважды при запуске. Итак, я начал регистрировать все, и вот что я нашел:

07-27 16:39:21.363    2129-2129/com... E/SURFACE_CHANGED﹕ imageRatio: 1.3333334 width: 1080 height: 1701 bitmap_width: 1080.0 bitmap_height: 810.0 canvas_width: 1080 canvas_height: 810 surface_width: -1 surface_height: -2

07-27 16:39:21.388    2129-2129/com... E/SURFACE_CHANGED﹕ imageRatio: 0.0 width: 1080 height: 1701 bitmap_width: 1080.0 bitmap_height: Infinity canvas_width: 1080 canvas_height: 2147483647 surface_width: -1 surface_height: -2

Наиболее важно, imageRatio, который в моем коде устанавливается только один раз, меняется на 0.0. Таким образом, устанавливая один или высоту или ширину растрового изображения в бесконечность. Если я поверну устройство, появится аналогичный набор из двух журналов с исходным imageRatio, установленным на 1,33... и затем изменяющимся на 0,0. Я не могу на всю жизнь понять, почему это так.

Во всяком случае, этого легко избежать. Я обернул свой код в это выражение if, указав (imageRatio > 0.0). И все же проблема сохраняется, ничего не меняется!

1 ответ

Решение

Хорошо, я понял это. Ширина и высота фактического SurfaceView не менялись в соответствии с размером растрового изображения, поэтому мне пришлось изменить размер SurfaceView, прежде чем будет вызван SurfaceChanged. Поэтому я переопределил onConfigurationChanged, чтобы изменить размер самого SurfaceView с помощью surfaceHolder.setFixedSize(), который в любом случае вызывает поверхность SurfaceChanged:

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);

    int screenWidth = screenSize.x;
    int screenHeight = screenSize.y;
    float width;
    float height;

    if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        screenHeight = screenSize.x;

        width = screenHeight * imageRatio;
        height = screenHeight;
    } else if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
        screenWidth = screenSize.x;

        width = screenWidth;
        height = screenWidth / imageRatio;
    } else {
        Log.e("UNSUPPORTED_ORIENTATION", Integer.toString(config.orientation));
        width = screenWidth;
        height = screenHeight;
    }

    surfaceHolder.setFixedSize((int) width, (int) height);
}

Затем я использовал SurfaceChanged, чтобы установить ширину и высоту холста и растрового изображения в соответствии с SurfaceView:

@Override
public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {
    bitmapWidth = width;
    bitmapHeight = height;

    canvasWidth = width;
    canvasHeight = height;

    try {
        canvasBitmap = Bitmap.createScaledBitmap(initialBitmap, (int) bitmapWidth, (int) bitmapHeight, true);
        surfaceCanvas = new Canvas();
        surfaceCanvas.setBitmap(canvasBitmap);
    } catch (Exception exception) {
        exception.printStackTrace();
    }
}
Другие вопросы по тегам