Масштабировать элементы пропорционально размеру экрана

моя кнопка на Nexus S (480x800) выглядит неплохо. Он занимает чуть меньше четверти высоты экрана. Когда я открываю свое приложение на Nexus 10 (2560x1600), кнопка кажется намного меньше. Я ищу способ, при котором моя кнопка правильно масштабируется пропорционально размеру экрана. Так что моя кнопка занимает даже на Nexus 10 ту же комнату пустого экрана, что и на Nexus S. Я знаю, что есть drawable папки, но они не решают мою проблему правильно. Например: Nexus 10 и Galaxy Nexus поддерживают xhdpi. Однако экран Nexus 10 намного больше. Так что моя кнопка будет занимать разное количество места на этих устройствах.

Спасибо !


person Lara    schedule 01.03.2014    source источник
comment
Правильная папка для Nexus 10 – drawable-sw1600dp, а для Nexus S – drawable-hdpi.   -  person Phantômaxx    schedule 01.03.2014
comment
Хорошо, но я уверен, что разных разрешений больше, чем разных папок с возможностью рисования. Так есть ли альтернативный способ?   -  person Lara    schedule 01.03.2014
comment
как правило, для ТЕЛЕФОНОВ вы следуете правилу drawable-XYZdpi (XYZ = l|m|h|xh|xxh|xxxh), а для ПЛАНШЕТОВ — drawable-swZYXdp (ZYX — меньшая ширина в пикселях, поэтому: ..., 1024, 1280, 1600, ...). Существует ограниченное количество разрешений планшетов, а также разрешений телефонов.   -  person Phantômaxx    schedule 01.03.2014
comment
Что бы вы сделали, если бы кнопка не была основана на изображении. Просто обычная кнопка. Файлы изображений не окажут никакого влияния на этот элемент.   -  person Lara    schedule 01.03.2014
comment
В любом случае я бы использовал dp/sp в качестве единиц измерения. И я бы использовал папки значений для измерений. В вашем случае используется values-sw1600dp. Таким образом, размер шрифтов будет соответствовать моему вкусу для каждого разрешения.   -  person Phantômaxx    schedule 01.03.2014
comment
Но папок со значениями даже меньше, чем папок с возможностью рисования, чтобы охватить каждое разрешение.   -  person Lara    schedule 01.03.2014
comment
Есть столько папок, сколько вы делаете. Более или менее это зависит от того, что вы предоставляете.   -  person Phantômaxx    schedule 01.03.2014
comment
Итак, если бы я создал папку с именем values-hdpi, Android распознал бы ее и использовал с папкой drawable-hdpi? Я надеялся, что есть способ установить размер определенных элементов, таких как кнопка, в процентах от размера экрана. Имхо было бы намного проще   -  person Lara    schedule 01.03.2014
comment
Согласен, было бы. но проц не вариант, в андроиде. Для этого существует обходной путь (одно измерение — ширина или высота) за раз: он называется вес и может использоваться только дочерними элементами макета, наследуемого от LinearLayout (например, RadioGroup, TableRow, .. .)   -  person Phantômaxx    schedule 01.03.2014


Ответы (1)


У вас есть два варианта здесь

<сильный>1. Эффективное использование папок Drawable Различные папки Drawable имеют связанные с ними параметры размер и плотность. Например, это вариации в соответствии с параметром размера: 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;
        }
person Parth Kapoor    schedule 25.03.2014