按比例缩放元素与屏幕尺寸

时间:2014-03-01 16:31:27

标签: android scaling

Nexus S(480x800)上的按钮看起来非常棒。它需要不到屏幕高度的四分之一。当我在Nexus 10(2560x1600)上打开我的应用程序时,按钮似乎要小得多。 我正在寻找一种方法,我的按钮按比例缩放到屏幕大小。因此,我的按钮在Nexus 10上的空屏幕与Nexus S上的相同。 我知道有可绘制的文件夹,但他们没有正确解决我的问题。例如:Nexus 10和Galaxy Nexus都是xhdpi。 Nexus 10的屏幕虽然更大。所以我的按钮会在这些设备上占用不同的空间。

谢谢!

1 个答案:

答案 0 :(得分:0)

你有两个选择

<强> 1。有效使用可绘制文件夹 各种可绘制文件夹都有一个维度密度参数。例如,这些是按尺寸参数的变化:ldpi = 240X320,mdpi = 320X480 hdpi = 480X800并且同样明智。另一个参数是密度:mdpi:160 dpi,hdpi:240-dpi,xhdpi:320-dpi。

您需要在PhotoShop中设计图像,并牢记这些参数,然后将相应的图像放入适当的可绘制变体(drawable-large-ldpi,drawable-xlarge-mdpi等)。我的意思是,在photoShop或其他一些图像编辑软件中,您需要为绘图画布指定像素密度和尺寸参数(如上所述),然后在该画布上创建图像。 (希望你理解我的意思:)。

<强> 2。以编程方式缩放图像 我在项目中多次偶然发现图像缩放问题,每次由于时间不够(和懒惰),我会对不太理想的解决方案感到满意。但最近我找到了一些时间来打击这个特殊问题。这是我的解决方案,我希望它对你也有所帮助。

Bitmap scaleDownLargeImageWithAspectRatio(Bitmap image)
        {
            int imaheVerticalAspectRatio,imageHorizontalAspectRatio;
            float bestFitScalingFactor=0;
            float percesionValue=(float) 0.2;

            //getAspect Ratio of Image
            int imageHeight=(int) (Math.ceil((double) image.getHeight()/100)*100);
            int imageWidth=(int) (Math.ceil((double) image.getWidth()/100)*100);
            int GCD=BigInteger.valueOf(imageHeight).gcd(BigInteger.valueOf(imageWidth)).intValue();
            imaheVerticalAspectRatio=imageHeight/GCD;
            imageHorizontalAspectRatio=imageWidth/GCD;
            Log.i("scaleDownLargeImageWIthAspectRatio","Image Dimensions(W:H): "+imageWidth+":"+imageHeight);
            Log.i("scaleDownLargeImageWIthAspectRatio","Image AspectRatio(W:H): "+imageHorizontalAspectRatio+":"+imaheVerticalAspectRatio);

            //getContainer Dimensions
            int displayWidth = getWindowManager().getDefaultDisplay().getWidth();
            int displayHeight = getWindowManager().getDefaultDisplay().getHeight();
           //I wanted to show the image to fit the entire device, as a best case. So my ccontainer dimensions were displayWidth & displayHeight. For your case, you will need to fetch container dimensions at run time or you can pass static values to these two parameters 

            int leftMargin = 0;
            int rightMargin = 0;
            int topMargin = 0;
            int bottomMargin = 0;
            int containerWidth = displayWidth - (leftMargin + rightMargin);
            int containerHeight = displayHeight - (topMargin + bottomMargin);
            Log.i("scaleDownLargeImageWIthAspectRatio","Container dimensions(W:H): "+containerWidth+":"+containerHeight);

            //iterate to get bestFitScaleFactor per constraints
            while((imageHorizontalAspectRatio*bestFitScalingFactor <= containerWidth) && 
                    (imaheVerticalAspectRatio*bestFitScalingFactor<= containerHeight))
            {
                bestFitScalingFactor+=percesionValue;
            }

            //return bestFit bitmap
            int bestFitHeight=(int) (imaheVerticalAspectRatio*bestFitScalingFactor);
            int bestFitWidth=(int) (imageHorizontalAspectRatio*bestFitScalingFactor);
            Log.i("scaleDownLargeImageWIthAspectRatio","bestFitScalingFactor: "+bestFitScalingFactor);
            Log.i("scaleDownLargeImageWIthAspectRatio","bestFitOutPutDimesions(W:H): "+bestFitWidth+":"+bestFitHeight);
            image=Bitmap.createScaledBitmap(image, bestFitWidth,bestFitHeight, true);

            //Position the bitmap centre of the container
            int leftPadding=(containerWidth-image.getWidth())/2;
            int topPadding=(containerHeight-image.getHeight())/2;
            Bitmap backDrop=Bitmap.createBitmap(containerWidth, containerHeight, Bitmap.Config.RGB_565);
            Canvas can = new Canvas(backDrop);
            can.drawBitmap(image, leftPadding, topPadding, null);

            return backDrop;
        }