Android: SurfaceView surfaceChanged Center in Parent
Android: SurfaceView surfaceChanged Center in Parent
我正在创建一个应用程序,它可以拍摄图像并将其置于屏幕中央以进行更改。我正在使用 SurfaceView 和 Canvas。我正在尝试将 SurfaceView 置于父 RelativeLayout 的中心。我让它工作,但它会在旋转时变得扭曲。所以我目前正在使用 surfaceChanged 方法来重置位图的大小和 canvas 当方向改变时:
@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();
}
}
缩放现在有效,但现在不居中。我还注意到背景的其余部分是黑色的,而不是以前的灰色。这会让我相信 canvas 超出了位图的视图。经过进一步检查,我注意到 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。因此将位图的高度或宽度设置为 Infinity。如果我旋转设备,则会出现一组类似的两个日志,其中原始 imageRatio 设置为 1.33... 然后更改为 0.0。我这辈子都想不通为什么会这样。
总之,这很容易避免。我将我的代码包装在一个指定 (imageRatio > 0.0) 的 if 语句中。然而问题依旧,没有任何改变!
好的,我明白了。实际 SurfaceView 的宽度和高度没有更改以匹配位图的大小,因此我必须在调用 surfaceChanged 之前更改 SurfaceView 的大小。所以我覆盖了 onConfigurationChanged 以使用 surfaceHolder.setFixedSize() 更改 SurfaceView 本身的大小,最终调用 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 设置 canvas 和位图的宽度和高度以匹配 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();
}
}
我正在创建一个应用程序,它可以拍摄图像并将其置于屏幕中央以进行更改。我正在使用 SurfaceView 和 Canvas。我正在尝试将 SurfaceView 置于父 RelativeLayout 的中心。我让它工作,但它会在旋转时变得扭曲。所以我目前正在使用 surfaceChanged 方法来重置位图的大小和 canvas 当方向改变时:
@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();
}
}
缩放现在有效,但现在不居中。我还注意到背景的其余部分是黑色的,而不是以前的灰色。这会让我相信 canvas 超出了位图的视图。经过进一步检查,我注意到 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。因此将位图的高度或宽度设置为 Infinity。如果我旋转设备,则会出现一组类似的两个日志,其中原始 imageRatio 设置为 1.33... 然后更改为 0.0。我这辈子都想不通为什么会这样。
总之,这很容易避免。我将我的代码包装在一个指定 (imageRatio > 0.0) 的 if 语句中。然而问题依旧,没有任何改变!
好的,我明白了。实际 SurfaceView 的宽度和高度没有更改以匹配位图的大小,因此我必须在调用 surfaceChanged 之前更改 SurfaceView 的大小。所以我覆盖了 onConfigurationChanged 以使用 surfaceHolder.setFixedSize() 更改 SurfaceView 本身的大小,最终调用 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 设置 canvas 和位图的宽度和高度以匹配 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();
}
}