Android 在画布中调整位图大小和位置以使其在不同设备中看起来相同的最佳方法?

Android 在画布中调整位图大小和位置以使其在不同设备中看起来相同的最佳方法?,android,canvas,surfaceview,tablet,Android,Canvas,Surfaceview,Tablet,我正在开发一个使用表面面板的游戏。我已经做了很多关于如何在画布上为多个设备正确缩放和定位可绘制内容的研究,我提出了一个解决方案,该解决方案在手机上运行良好,但在平板电脑上尝试时存在一些缺陷。我知道我可以在平板电脑上使用不同的资源,我可能最终会这样做,但现在让我们假设我不想这样做,我想在市场上的每一部不同的手机上使用相同的资源 我拥有的所有资源都位于hdpi文件夹中,它们的大小适合480x800设备 我的方法与上述方法类似,请查看下面的解释,我想知道是否有更好的解决方案 我有一个Galaxy S2

我正在开发一个使用表面面板的游戏。我已经做了很多关于如何在画布上为多个设备正确缩放和定位可绘制内容的研究,我提出了一个解决方案,该解决方案在手机上运行良好,但在平板电脑上尝试时存在一些缺陷。我知道我可以在平板电脑上使用不同的资源,我可能最终会这样做,但现在让我们假设我不想这样做,我想在市场上的每一部不同的手机上使用相同的资源

我拥有的所有资源都位于hdpi文件夹中,它们的大小适合480x800设备

我的方法与上述方法类似,请查看下面的解释,我想知道是否有更好的解决方案

我有一个Galaxy S2用于测试我的应用程序。因此,我的第一种方法是手动将所有内容直接插入画布中,尝试并找到所有内容的最佳位置。以第一个字符位置为例:

draw_x = (float) (19);
draw_y = (float) (279);
canvas.drawBitmap(toDrawBitmap, draw_x, draw_y, null);
当我第一次在不同的设备上测试它时,一切都一团糟,超出了规模。所以我想用密度来扩展资源

 // I am dividing by 1.5 because my initial positions are on a high density device
 // so when it goes for a medium density it should scale for 0.66 and a small density 
 // for 0.5 of my positions. 
 float scale = getResources().getDisplayMetrics().density /1.5;
 draw_x = (float) (19) * scale;
 draw_y = (float) (279) * scale;
 canvas.drawBitmap(toDrawBitmap, draw_x, draw_y, null);
在第一印象中,这就像一种魅力。我所有的角色都在合适的位置上。但我注意到,如果设备的宽度/高度与我正在使用的Galaxy S2不同,那么问题就开始了。虽然所有的东西都被正确地放置在屏幕上,但图像的一部分被从屏幕上剪下来,画布被计算得比手机屏幕大

星系S2是480x800。我的背景也是480x800。当我在模拟器上用分辨率为320x480的小屏幕测试它时,Android并没有像我预期的那样正确缩放我的背景。它给了我一个比画布320x533更大的背景,而不是缩放到合适的分辨率

通过一些简单的数学计算,我们得出320x533/480x800=0.66。因此,它不是在画布中正确缩放背景,而是使用设备的密度进行缩放

所以我对这个问题的解决方法是我能想到的最简单的。我知道我背景的分辨率,我知道手机的分辨率,所以我可以计算出我需要的比例并强制调整大小

 //Set the proportions for scaling in multiple devices
 public void setProportions(float screenWidth,float ScreenHeight,Bitmap background){

     this.heightProportion = ScreenHeight/background.getHeight();
     this.widthProportion = screenWidth/background.getWidth();

 }  

 public Bitmap scaleBitmaps(Bitmap bitmap) { 
         Bitmap out = Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * widthProportion), 
                    (int)  (bitmap.getHeight()*heightProportion), false);         
         return out;
     }
这对绘图的大小很好,所以我只需要对位置做同样的操作,使用比例和这个新的比例,我可以使用固定大小的背景图像来计算

 public float convertX(float x){ 
     return x* scale * widthProportion;
 } 


 public float convertY(float y){ 
     return y* scale * heightProportion;
 } 

//calculate the positions applying the scale and the proportion
draw_x = convertX((float) (19));
draw_y = convertY((float) (279));
//draw the bitmap with the scaled position
canvas.drawBitmap(toDrawBitmap, draw_x, draw_y, null);
长话短说,为了正确地定位可画片,我在设备中手动设置了所需的位置,计算了密度之间的比例以及背景图像大小和屏幕大小之间的比例。 为了重新调整绘图的大小,我只使用了比例,因为android会自动应用密度比例

我在几种不同的手机和平板电脑上进行了测试,这种方法非常适合手机。在平板电脑上,它给了我一些小错误,在重新调整尺寸的抽屉

最后,我的问题是,这个解决方案有什么问题?我能让它在每一部手机上都能正常工作吗?或者有更好的解决方案吗


请注意,这对画布是严格的。如果在XML布局中使用相同的背景,则每个手机的背景尺寸都会正确调整。如果我不清楚或者我应该提供更多信息,请让我知道

在解决这个问题之前,首先要知道的是设备电话运行系统。尽管您建议手机选择hdpi或其他版本,但这取决于每款手机的运行系统

A.尺寸匹配问题

问题是如何处理位图。尽管您使用任何数学公式重新缩放位图,但原始位图的大小对于每个不同的手机将有不同的输出。要解决此问题,必须将位图的inScaled设置为false

B.位置装配问题

因此,你有问题,在拟合位图的大小,位图的位置将同步的位置取决于你的手机屏幕大小。您应该定义背景对象并基于背景定位对象x和y。例如,如果你想把一个物体放在电话屏幕中间,不管我们使用什么电话,代码必须是'

canvas.drawBitmaptoDrawBitmap,background.getwidth/2,background.getheight/2,null

解决装配位置问题


让我知道发生了什么。

在解决此问题之前,您必须知道的第一件事是关于设备电话运行系统。尽管您建议手机选择hdpi或其他版本,但这取决于每款手机的运行系统

A.尺寸匹配问题

问题是如何处理位图。尽管您使用任何数学公式重新缩放位图,但原始位图的大小对于每个不同的手机将有不同的输出。 要解决此问题,必须将位图的inScaled设置为false

B.位置装配问题

因此,你有问题,在拟合位图的大小,位图的位置将同步的位置取决于你的手机屏幕大小。您应该定义背景对象并基于背景定位对象x和y。例如,如果你想把一个物体放在电话屏幕中间,不管我们使用什么电话,代码必须是'

canvas.drawBitmaptoDrawBitmap,background.getwidth/2,background.getheight/2,null

解决装配位置问题

让我知道会发生什么