Can someone let me know, what if there is some dimen by same name in app and a library.
dimen.xml inside app
<dimen name="activity_horizontal_margin">10dp</dimen>
dimen.xml inside library
<dimen name="activity_horizontal_margin">12dp</dimen>
Which one will be used at runtime?
I can try it, but I will not be clear for the reason to being used as final value.
You can try to redefine size in your dimensions.xml:
<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="activity_horizontal_margin" tools:override="true">12dp</dimen>
</resources>
Use with care as this is a hack, not an actual solution. The solution might not work if the resource's name is changed in the future Library release.
When you redefine(the same name) a dimension resource is like overriding the lib resource. Just like you override a class method.
I think the answer would be:
It depends on what layout is being populated, if it's an activity layout from an app module then app's dimen will be used and vice versa..
This is a great question I don't know why it got downvoted. While the selected answer is true there is slightly more nuance to it, Android chooses the "most specific" resource which takes precedence over app resource values.
e.g. consider the boolean <bool name="isTablet">true</bool> in a library, setup like so:
values - false
values-sw600dp - true
And in an app like so:
values - false
values-sw600dp-land - true
What is the value of the boolean on a 1280x800 portrait tablet when called from the app?
The answer is true, even though the app specified it to be true in landscape only!
Related
I have a project in Android Studio that uses different flavors for different colors (some other things as well, but they don't matter).
What I would like is to see how a certain UI element (all defined by xml files) looks with non-default flavor?
Let's say I have to flavors, flavor A which is default and flavor B which is not. Lets say flavor A main color is red, and flavor B main color is green.
When I open layouts, they will always show as red, no matter what flavor in build variants is selected.
I'm sure there is a way to do this, but I don't know how.
Edit1: Seems I didn't explain it (thought it was implicit).
My resource files for flavors are already in different folders. Colors in resource files are of the same name. That is not the problem, the problem is that I can't see colors in layouts inside of Android Studio.
Colors are in separate folders and it works as it should. When I build and install flavors, they use their colors. But when I open a layout, it always shows with default colors in Android Studio
Let me blow out some dusts first :
You're getting default colors in your layout files is because, your layouts resides under default folder (main package in this case).
What happens here is that, when you create build of particular flavor (let's say flavorA), packaging system takes files specific to that flavors that are duplicated from default folder and replace it to provide you flavor-specific build.
So, your generated apk file contains flavor specific files (colors.xml in your case) + default files from main (res folder of main like all layouts and other resources & your class files too) that are not the part of your flavor specific folder.
That's why everything works perfectly.
Now back to point : (Hack)
What should you do to see layouts with flavor specific colors?
"Although I would not recommend this way" unless you're having different layout logic for flavor specific build, all you can do is place particular layout files (just to see rendered output) in your layout folder under your flavorA directory.
So, It'll now take colors from flavorA folder and render you layout in IDE with that colors in your layout file.
Note: Again, this is just a hacky way to see different things in flavor specific way, not a solution. Even though I don't think there's even solution for this problem because, this is not a problem & this is how multi-flavor gradle build system works and that's not a bug in this system.
Edit:
So, after some research, I find out how you can achieve such thing that 'you get rendered output based on your flavor colors'.
Let's say you're having different colors based on your flavors like below :
Now, contents of flavorB & flavorW are different for colors.xml file but having same color attributes like:
flavorB contains :
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#757575</color>
<color name="colorPrimaryDark">#212121</color>
<color name="colorAccent">#607d8b</color>
</resources>
flavorW contains :
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#6d4c41</color>
<color name="colorPrimaryDark">#3e2723</color>
<color name="colorAccent">#33691e</color>
</resources>
As you can find out that number of color elements are the same but just values are different.
TL;DR
Solution : In such case, you can simply delete colors.xml from your main/res/values folder. It won't generate any error unless you're missing any flavor specific color attr for your "current build variant".
check out main dir for my project :
(As you can see here that, main resource directory doesn't contains any colors.xml file)
So, if you'll try changing your build variant and look at any layout file from main it'll opt out with that specific product flavor color for you.
Note : Beware that, If you add or remove one color from one flavor remember to also add/remove it to other flavors too or else your project might get error while building. (you can also do the same trick with other resources too like drawables, layouts, dimensions etc. just make sure every flavor contains it all with the same resource name)
Im not sure if its possible to affect layout preview with flavours, but its definetely possible with themes, so let me suggest a workaround.
1) Create two themes in your main source set:
<style name="MyStyle">
<item name="colorPrimary">#44f</item>
</style>
<style name="MyStyle.Red">
<item name="colorPrimary">#f44</item>
</style>
That is basically enough to customise layout preview: you can select theme you want.
2) To make your layouts flavor-dependent, create a theme that will inherit either MyStyle or MyStyle.Red depending on flavor
In main source set:
<style name="MyFlavorDependentStyle" parent="MyStyle"/>
In flavor source set:
<style name="MyFlavorDependentStyle" parent="MyStyle.Red"/>
and use MyFlavorDependentStyle in your layout.
if the colors are defined in XML just move the colors definition from main/colors.xml to flavorA/colors.xml and flavorB/colors.xml
Is it possible to use the reference of a dimension resource in another dimension? What i mean is something like this:
File dimen.xml:
<dimen name="test1">18sp</dimen>
<dimen name="test2">#dimen/test1</dimen>
It works the way i posted
<dimen name="test1">18sp</dimen>
<dimen name="test2">#dimen/test1</dimen>
I would suggest to consider one more thing when using this.
I get what you said in your comment, but either there is a link between the two values or there is not and you should distinguish between these two possibilities.
If there is no link between test1 and test2 and they are independent and the fact that they hold the same value is mere coincidence, then you shouldnt suggest a link between the two. Instead just set the same value twice.
Why do you want create a second dimension with the same value as first ?
Don't create second dimension, but use first !
I don't want to specify hard coded test size values in my layout.xml, hence i am using the following specification :
android:layout_height="#integer/intervalViewHt"
and
#integer/intervalViewHt value is as follows:
<integer name="medium">15</integer>
Now, the while inflating android is creating a problem saying that it cannot inflate the view. I want to actually specify value in dp so the actual value should be like
android:layout_height="15dp"
Can anyone help me here ?
What you're looking for are "dimensions" rather than plain integers.
Declaration:
<dimen name="intervalViewHt">15dp</dimen>
Usage:
android:layout_height="#dimen/intervalViewHt"
Have a look at the given link for more examples in the Android docs.
I use something like this for text size across different devices. It's java based, not xml.
tvOutput.setTextSize(TypedValue.COMPLEX_UNIT_DP, getResource().getInteger(R.integer.medium));
I haven't tested the code so you might have to play with it. I'm sure you could do something like.
button1.setHeight(TypedValue.COMPLEX_UNIT_DP, getResource().getInteger(R.integer.medium));
Though again I haven't tried it and you may need something different then TypedValue
What if you give it a String rather than an int. i.e in strings resource you have a string "15dp" that you reference
Similar to how you can have two folders res/values and res/values-xlarge, and in each you can have a dimens.xml file with different dimensions...
I want to be able to store some integers (not sizes in dp or anything like that, just plain integers) like that. Is this possible to do in .xml? Or if not, how could I do that programmatically?
If you must know why: I am displaying a list where the user can choose to show the number of results at a time. For smaller screens, I want the default list length to be smaller than the default list length for larger screens.
Yes, there's a mechanism exactly like that. Just create an XML file in res/values and related folders and instead of something like:
<resources>
<dimen ...>
</resource>
You can provide an integer resource:
<resources>
<integer name="i">234</integer>
</resource>
However, in your specific scenario I'd also consider if simply changing the related layout file makes more sense.
Sure, you can do that. Just like storing a string Ressource you can store Integers.
Taken from the documentation:
XML file saved at res/values/integers.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="big_screen_width">12000</integer>
<integer name="small_screen_width">320</integer>
</resources>
And the code would look like that
Resources res = getResources();
int bigScreen = res.getInteger(R.integer.big_screen_width);
You can store things programmatically by using SharedPreferences.
I am teaching myself Android using Eclipse, the Android plug-in, and Sams "Teach Yourself Android Development" book. I have this weird little problem. I've been able to create xml files in the res/values directory that hold strings and color values (colors.xml and strings.xml). I have been able to reference these values in the properties of my Android screens (the xml in res/layout), for example setting the "Text" and "Text color" properties with references like "#string/topTitle" and "#color/titleColor," where topTitle and titleColor are defined in the xml files.
BUT: when I create a file called "dimens.xml" and have font sizes in it, Eclipse correctly puts this file in res/values, but when I try to reference these values, e.g. "#dimension/titleFont" I get an error "No resource found that matches the given name." I've tried lots of different names, I've tried "#dimens" instead of the type, still nothing. If I go into the layout xml file and set it explicitly to a font size, e.g. 22pt, it works.
So Eclipse recognized my "dimens.xml" file when I made it well enough to put it in res/values, and lets me edit it, and shows it full of (dimension) values. It just doesn't recognize my referring to it in other xml files.
The book I'm using doesn't actually show a dimension example so I must be doing something wrong. I checked the Android docs but couldn't see any problem.
Any help appreciated. Thanks.
The correct way to refer to a dimension variable (stored in your dimens.xml (don't think the name here really matters though, it's what's inside that does)) from another xml file is like this:
"#dimen/nameOfVariable"
Notice that it is neither dimension, dimensions or dimens, but dimen!
If you look inside your xml file where you have your values, this will make sense as dimen is the name of the xml elements storing dimension values:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<dimen name="someDimension">5dp</dimen>
<dimen name="anotherDimension">10dp</dimen>
</resources>