I thought I had this device density/size thing down, but apparently that is not the case. I have created a new hardware definition within Android Studio using the following dimensions and size.
9.7"
768 x 1024
This results in an ldpi device, which is what I am after. This was mirrored off of the HP Touchpad device.
I am using several dimens files within my application which are contained within their associated values folder with 2 resource qualifiers each. A typical values folder in my app looks like this.
values-sw320dp-xhdpi
Using the information above, I believe this should result in the system looking for the dimens file in my values folder shown below.
values-sw480dp-ldpi
I arrived at this conclusion by taking the pixel dimensions of 768 x 1024 and multiplying them by .75 which would result in a with and height in dp of 576 x 768. Since the smallest width is 576, this should use the values folder referenced above of values-sw480dp-ldpi.
I know that it is not using the values specified in this dimens file because the value shown in the layout is from one of my other values folder/dimens files. Additionally, it is not actually using the values from the file that the layout is referencing either, as changes to that dimens file have no impact on the layout. It simply is stopping on the first one seen (or something) but not actually using the value. I have encountered this situation many times and the issue is always fixed by getting the "correct" values folder defined with the appropriate resource qualifiers. The issue here is that I don't know what the system is actually trying to use and it clearly is not coming up with the same calculations I am.
Here is a screen shot of the device I have build in Android Studio.
Android supports combination of qualifiers in defined order of priority. Here in Table 2. you can see this list.
And here you have fine description of how Android finds the best-matching resources.
Also, I wonder what is the reason you create values folders with Screen pixel density (dpi) qualifiers. I could be wrong, but I think that density matters only with drawables/mipmaps etc.
Related
I've got a Pixel XL and I like to keep the screen size set to small. However, the default size for the Pixel is defined by Google as xxxhdpi, so my increasing the dpi isn't "detected" so no scaling is triggered.
When making an app, I can't seem to create a folder called xxxxhdpi or xxlarge, so I'm kind of at a loss as to how to define the layout for the higher DPI.
I found a resource suggesting to simply define the dpi, i.e. calling the folder 720dpi, but Android Studio throws a compile error if I do that.
Does anyone have any idea how I can make the app show up correctly on my phone?
Can you make minmap-xlarge resource folder? but not sure whether Pixel xl device will read from it. Here is the screenshot.
Upon creating the new project in android studio in the following path were created two xml files by default.
..res/values/dimens.xml
..res/values/dimens.xml(w820dp)
Am aware of the file dimens.xml where we can define the dimensions for the elements, but why the second file dimens.xml(w820dp) created by default.
Can someone please shed lights on why it is needed and when we can use it.
You can define several folders for each desired screensize in Andorid Studio. In your case, android studio defines values folders where you define dimensions (measurements) for scaling tablets or phones.
E.g. it defines two values folders like:
values-large
values-xlarge
or in your case
values-w820dp
Now inside this folders, a dimen.xml file is defined, where you can put your measurements in (unit dp) for the corresponding screensize.
Define a measurement like this:
<dimen name="value1">17dp</dimen>
Then embedd this sizes in your layout xml, like:
android:layout_height="#dimen/value1"
Depending on the screensize, the system will load the correct measurements from this folders, e.g. if you have a screen size large only the defined values in folder values-large will be loaded.
For more information, also have a look at https://developer.android.com/distribute/essentials/quality/tablets.html
EDIT1: So basically if you see the file dimen.xml(w820dp), the values in there are only used, if the app is executed on displays with 820dp and above, in this case, it means tablets.
In fact you have not file named ..res/values/dimens.xml(w820dp) at all in your project structure (check yourself). What you have instead is ..res/values-w820dp/dimens.xml file but to make editing right file easier, Android studio will (in Android view) show it as such. This file will be used by the framework on devices with display width 820dp or higher:
Specifies a minimum available screen width, in dp units at which the
resource should be used—defined by the value. This configuration
value will change when the orientation changes between landscape and
portrait to match the current actual width.
On other, "plain" dimens.xml will be loaded. See Providing Alternative Resources documentation on resource qualifiers to find out more about possible options and benefits.
Main use case of these files is to Support variety screen resolutions for user interface
dimens.xml
Android automatically take values from this file for device with dpi less than 820dp
dimens.xml(w820dp)
Android automatically take values from this file for device with dpi greater than 820dp
How to use
Declare dimension in these files with same name(dimens.xml)
<dimen name="button_width">200dp</dimen>
<dimen name="button_height">40dp</dimen>
Change only in their values (dimens.xml(w820dp))
<dimen name="button_width">400dp</dimen>
<dimen name="button_height">80dp</dimen>
w820dp
for screens with more than 820dp of available width. This would include 7"
and 10" devices in landscape (~960dp and ~1280dp respectively)
w820dp is a qualifier value to provide alternate values for different dimensions. This is used to localize to device types properly.
I have a simple layout file with one TextView (for testing). I am attempting to change the size of the text based on the value of a dimen within the appropriate values file based on the device selected. I can make this work for all devices available within Android Studio with the exception of Nexus 5X/6/6P.
Let's take the Nexus 6 as an example.
1440 x 2560 - 560dpi
560dpi is an xxhdpi device (x3)
So dividing the resolution by 3 we get 480 x 853
The smallest width of this device being 480.
I have values folders for the following:
sw320dp
sw480dp
sw600dp
sw720dp
sw800dp
Actually, I have 5 of each of these, one each for the densities of mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi.
I have set the textSize property of my TextView in the layout to use the dimen of myTextValue which exists with different values in each of the different dimens files mentioned above.
When opening this layout file, it is showing that the values/dimen is being used and the value shows as 30, which happens to be the value from my values-sw320dp-hdpi folder.
Unless I am totally missing something, this is completely wrong. It should be using the dimen from the values-sw480dp-xxhdpi folder.
To complicate things even further, even though I can tell which dimen file it used, making changes to that file does nothing to the layout, like it can't do anything with it / is not using it.
This is only happening for the above 3 mentioned devices in Android Studio and is only happening with one of my 5 original layout files and any new files I create. I have 4 other layout files which 'appear' to be working as I'd expect.
This is driving me crazy, so if anybody has any suggestions, I'd greatly appreciate it. Thanks
This was an oversight on my part. The three devices which 'seemed' to not be working correctly all were looking for a sw320dp-xxxhdpi values file and when one did not exist (my situation), it just used what matched best but then making changes to any of the other values files had no impact, which makes sense.
From what i saw android uses the dimens found in the bigger folder that is smaller or equal to device dp resolution. So in fairness it just iterates from the biggest dimen folder that is smaller or equal the device dp resolution to the default folder from what i can tell there is no "matching" involved it uses thresholds which makes it very fast and very easy to predict which value will actually be used.
values | sw220dp | sw320dp | sw360dp | sw480dp | sw600dp | ...etc
.................................|device resolution DP
Screen resolution and size together with some other settings give the device a dp resolution ex 380 x 640 dp so this is smaller the 480 so first folder it checks is 360 -> towards default which is found first it is set. One more thing for the most part you can't control what dp resolution the device uses although there is a scaling setting that can be used to scale the layout and sp dimens used.
to find out device dp use this:
val width = resources.configuration.screenWidthDp
val height = resources.configuration.screenHeightDp
I know there are many questions like this, I have read many blogs and questions on this and I am not satisfied by what I have understand.
I want to support multiple screens and resolutions like hdpi, xxxhdpi etc.
And i am using dimens.xml for this purpose. But m still unclear about how to calculate exact dp value for different screens.
For example if 48dp x 48dp ImageView is proper for hdpi device, what values should i define for xxhdpi device? Is there any fixed calulation just like there is for drawable images?
I am using these folder for trying to support multiple screens :
values-sw320dp-hdpi
values-sw320dp-xhdpi/xxhdpi/xxxhdpi
There are few problems I am facing currently
Though defining values in respective dimens.xml works almost for most of the devices, there are few devices which takes wrong values
For example I have Lg optimus G that is xhdpi device, but it reads values from values-sw320dp-xxxhdpi's dimens.xml instead of xhdpi one
I am not able to calculate the exact value for each resolution (hdpi,xhdpi etc), so the view which looks perfect in hdpi device, seems little large or small in xxxhdpi as I can't guess the value like if hdpi view size is 48dp then xxxhdpi should be of 64dp or something as I don't know the exact approach.
Also while searching for supporting different screens, I read many times about calculating dp at runtime based on density or calulating pixels etc.
I am too confused about all this. Please help me in understanding and learning the proper way of making responsive apps.
You can use resource qualifiers to specify different sizes for Views.
If you want the width of an ImageView to vary based on the size of the screen, create a new dimension in your dimens.xml file called image_view_width (for example).
This then essentially creates a copy of the dimens.xml but adding the 'Size' qualifier. This will create another version of the dimens.xmlfile, and any device that meets your specified qualifications will use that version of dimens.xml. You then add image_view_width to this new file and give it a different (smaller/bigger) value. You can do this as many times as you want and with as many different qualifiers as you want.
Finally, when you want to use this value in your layouts, you only have to type:
android:layout_width="#dimen/image_view_width"
and android will do the rest for you.
Hope this helps!
I'm working on a Android project where I need to build my layouts based on a JSON layout file. This same file is also being used on an iOS app. So there is 1 file which will render the same layout on the Android as well as on the iOS.
The JSON layout file defines its font sizes based on the default iOS font unit.
From the Android docs:
Points - 1/72 of an inch based on the physical size of the screen.
And as far as I can find, iOS font sizes are also defined as 1/72 of an inch.
So based on this info, I'd say the following should be enough:
view.setTextSize(TypedValue.COMPLEX_UNIT_PT, fontSizeInIosUnit)
This however results in the text being too large. And it also seems to differ per device (which is weird since points should always appear in the same physical size).
If you want fonts to resize properly according to screen size you should use dp/dip instead.
So try this instead:
view.setTextSize(TypedValue.COMPLEX_UNIT_DIP, fontSizeInIosUnit);
Now this might not be exacly the same but in my experience this gives the best results. If it doesn't have the proper size then figure out what size you need on Android as the base size and then go with that instead.