I have a layout that has an image that needs to be displayed at different aspect ratio's depending on the screens size.
I tried to do it like this
app:layout_constraintDimensionRatio="#dimen/image_ratio"
And then specifying the different ratios in various dimens.xml files for the appropriate screen size.
<dimen name="image_ratio">3:1</dimen>
And I got it working exactly how I want it in the layout editor, but it won't compile.
Android resource compilation failed
Output: [...]/values-sw600dp-v13.xml:11: error: invalid dimen.
Not sure why it says the error is on line 11, as the problematic dimension is actually on line 58
I think its stupid that something that seems like it should work, and does work in the editor, doesn't work when it comes time to compile.
So how should I achieve this result?
layout_constraintDimensionRatio attribute requires string attribute as ratio to layout dimension (i.e. 1:1) or with context of height or width like (i.e. W, 1:2 or H, 1:2).
dimens.xml requires dimensions required by app to be declared, hence you need to add your specific attribute to strings.xml.
Thanks to Jeel Vankede, I solved this.
His proposed solution of providing the ratio from strings.xml would work, but would generate an extra set of strings.xml files for all the different screen sizes.
This is unnecessary, as you can store strings in your existing dimens.xml file.
I simply switched out the <dimen> tags for <string> tags, and then used #string/image_ratio instead in my layout file.
Related
This seems like a bug but maybe I'm doing something really silly and just can't see it. I have these value files:
The integer value files are behaving as expected. Inside the default integers.xml I have:
<integer name="card_item_columns">2</integer>
and for the integers.xml(w840dp) I have:
<integer name="card_item_columns">3</integer>
But when it comes to the dimens files, only the sw600dp one seems to do anything. For the dimens.xml(sw600dp) I have this:
<dimen name="card_width">264dp</dimen>
and for the dimens.xml(w840dp) I have this:
<dimen name="card_width">400dp</dimen>
If I use a Nexus 7 emulator device in portrait it shows 2 columns. When I rotate it I see 3 columns as expected. This proves that it's at least 840dp wide as that integers.xml(w840dp) file is the only place it can get 3 columns from.
However if it's w840dp why doesn't it use the card width value in the dimens.xml(w840dp)? Is this not possible? Can a "w" qualifier not override an "sw" qualifier? I think it should.
I can adjust the value in the sw600dp file and the change is reflected, showing that it's getting called correctly from the layout file.
What basic concept am I not getting here? I find it hard to believe that there is a bug here. Surely if there was, other people would have noticed it. Spot the silly error to get some points. Or give me a clue that leads to the solution. Thanks.
The documentation on the Android site regarding resource qualifier precedence is pretty comprehensive:
Providing Alternate Resources
All other things being equal, smallestWidth has higher precedence than Available width
Configuration | Qualifier value
smallestWidth | sw<N>dp
Available width | w<N>dp
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.
How can I set margins(Left,Top,Right,Bottom) to these ImageView so that it will display correctly on multiple screen sizes in Android ? Also I need to handle click events on these Images.1
Well the whole point of using DP is so that you don't have to worry about this. Margins will be roughly the same across devices, but if you're relying on lining things up on one particular device resolution/density combination, you'll definitely be in for a surprise when you test on other devices.
That said, if you do need to specify different margins for different screen sizes, simply add an XML file in res/values -- something like dimens.xml:
<resources
xmlns:android="http://schemas.android.com/apk/res/android"
>
<dimen name="my_view_margin">10dip</dimen>
</resources>
Then add one of these XMLs for every specific device qualifier that you need to (e.g. values-large, values-sw600dp, values-xlarge, etc.) and modify the value as you see fit. When you want to use these dimensions in a layout, just use:
android:layout_margin="#dimen/my_view_margin"
And Android will pick the correct value for whatever device it happens to be running on.
provide different values folders and set values.
For Ex.
values,
values-sw350dp,
values-sw480dp,
values-sw600dp,
values-sw720dp etc.
In my layout XML files, I reference a lot of parameters through a separate files called dimens.xml.
For example, dimens.xml contains parameters like these:
<dimen name="textSize_normal">20dp</dimen>
<dimen name="buttonTextSize_normal">15dp</dimen>
<dimen name="editTextSize_normal">17dp</dimen>
<dimen name="buttonHeight_normal">37dp</dimen>
<dimen name="margin_normal">5dp</dimen>
And in my main.xml, for example, I would set the text size for a TextView by doing something like this:
android:textSize="#dimen/editTextSize_normal"
It works great.
Now, my questions is, is it possible to set the values for the dimen variables in my dimen.xml file programmatically from my main activity? What I am trying to do is fetch the screen size, and set, for example, the textSize based on a fraction of the height of the screen so that it is easily adaptable to any screen size. I have all that figured out, I just need your help to figure out how to set the dimen variables in my code.
Now, my questions is, is it possible to set the values for the dimen variables in my dimen.xml file programmatically from my main activity?
No.
What I am trying to do is fetch the screen size, and set, for example, the textSize based on a fraction of the height of the screen so that it is easily adaptable to any screen size.
Ignoring that this is an odd UI approach, the way to do that is to delete your android:textSize attributes and to change the text size at runtime using setTextSize() in Java.
I have all that figured out, I just need your help to figure out how to set the dimen variables in my code.
You don't "set the dimen variables". You apply your calculations to the widgets, via setters like setTextSize().
No, you can't edit the Resources files on runtime, they are already compiled and generated.
You should use density independent pixels in all your resources, so that dimensions can adapt to screen size. You don't need to calculate that values at runtime. If you want to have a different layout for different screen sizes, then consider using multiple resource files.
Read this guide.
i guess what you mean is to change the size depending on the device's screen size..
which can be made by creating multiple dimens.xml files in folders like values-hdpi, values-xhdpi, values-xxhdpi, values-mdpi,.. and then on runtime the compiler will choose the dimen depending on the dpi
i actually didn't try this before but i read it
here.. take a look at this:
http://developer.android.com/guide/practices/screens_support.html#qualifiers
I'm working on a project, where in the textview the dimension of text is mentioned in a file main_dimens.xml in values-1024x768 folder. But i need a different text size for specific language(say pt).
<dimen name="main_digitalclock_size">18dp</dimen>
I need 12dp for pt language. So i tried to add the above line of code in strings.xml of values-pt folder, also created a folder values-pt-1024x768 and putted in it. But still size is 18dp only.
Are you sure you named your resource folders correctly? I looked up the rules that the Android OS uses when determining which resources to use here:
http://developer.android.com/guide/topics/resources/providing-resources.html#AlternativeResources
It looks like the way to specify the usable screen size may be different from what you're using.