Мащабирайте елементите пропорционално на размера на екрана

бутонът ми на Nexus S (480x800) изглежда доста добре. Заема малко по-малко от една четвърт от височината на екрана. Когато отворя приложението си на Nexus 10 (2560x1600), дъното изглежда много по-малко. Търся начин, при който бутонът ми се мащабира правилно пропорционално на размера на екрана. Така че бутонът ми дори на Nexus 10 заема същата стая на празния екран, както на Nexus S. Знам, че има папки с възможност за рисуване, но те не решават проблема ми правилно. Например: 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 е второстепенната ширина в px, така че: ..., 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? Надявах се, че има начин да задам размера на определени елементи като бутон, процентно спрямо размера на екрана. Това ще направи много по-лесно IMO   -  person Lara    schedule 01.03.2014
comment
Съгласен съм, би било. но процентите не са опция в Android. Има заобиколно решение за това (1 измерение - ширина или височина) наведнъж: Нарича се тегло и може да се използва само от дъщерните елементи на оформление, което наследява от LinearLayout (като RadioGroup, TableRow, .. .)   -  person Phantômaxx    schedule 01.03.2014


Отговори (1)


Тук имате две възможности

1. Ефективно използване на папки с възможност за изчертаване Различните папки с възможност за изчертаване имат свързани с тях параметър dimension и density. Например това са вариациите според параметъра на размерите: 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