How to use a theme defined variable in res/values/dimens.xml? - android

Howdy.
In my themes.xml definition, I have the following:
<style name="mythemename">
<item name="d_myvar">100dip</item>
</style>
I would like to be able to reference this in res/values/dimens.xml like so:
<dimen name="myvar">?d_myvar</dimen>
Alas, this doesn't work. When I try to use the #dimen/myvar as the height of a LinearLayout, the app crashes with the error "You must supply a layout height attribute."
I have also tried
<dimen name="myvar" value="?d_myvar" />
But that won't compile.
How can I define #dimen/myvar in my xml so that it loads the ?d_myvar variable defined in the theme?
Thanks!

I saw your help request on the Italian Startup Scene.
Unfortunately, according to the syntax of the dimen tag:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen
name="dimension_name"
>dimension</dimen>
</resources>
you simply can't do it. In fact, you can reference theme attributes when the syntax specifies:
?[package:][type:]name
Solutions:
Gix's answer would be the standard way of defining and reusing dimensions.
Maybe you can reorganize your code to reuse d_myvar through inheritance?
As a last and desperate resort, I would go for a shell script that automates the process of variable substitution using xml command line tools. I have never personally used them, but see for example xmllint, xmlstarlet or this article.

Put the 100dip part in your dimens.xml like so:
<dimen name="myvar">100dp</dimen>
then in your theme you can reference it as #dimen/myvar if you need, or you can reference it in code using R.dimen.myvar
In other words, you don't set the dimension in theme and then reference it in dimens.xml, but you go the other way around. You set the dimension in dimens.xml and then reference that in your theme/style xml.

In styles.xml
<resources>
<attr format="dimension" name="exampleDimension"/>
<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
<item name="exampleDimension">100dp</item>
...
</style>
</resources>
Then in your other xml to use the new attribute, you would use it like this
android:padding="?attr/exampleDimension"

Related

Android Studio reusable xml value

I've got this super simple question I can't find an answer to.
I want to make a variable which I could then use for multiple elements.
Something like this in strings.xml:
<resources>
<string name="textSize">20sp</string>
</resources>
...
<EditText android:textSize="#string/textSize" />
But this does not work.
I was able to accomplish what I wanted the following way in themes.xml:
<style name="textSize">
<item name="android:textSize">20sp</item>
</style>
...
<EditText android:theme="#style/textSize" />
But it seems too complicated for just a single value, is there a better way?
As suggested in the comments, this looks like a dimen property rather than a string.
Just like strings.xml, you can have another file (usually dimen.xml) with dimensions. Your case could look like this:
<resources>
<dimen name="bigText">20sp</string>
</resources>
It also allows you to have different settings for different configurations (for example, screen sizes here: How to define dimens.xml for every different screen size in android?).
You can find the documentation here:
https://developer.android.com/guide/topics/resources/more-resources?hl=en#Dimension

How to set text size for app in one place?

I want to be able to set the text size on an application wide basis.
So I will need to be able to access the value in code and xml.
I tried putting the size in my dimens.xml as follows...
<item name="text_size_small" type="dimen" format="float">15.0</item>
But I was unable to re-use this in xml i.e...
android:textSize="#dimen/text_size"
Gives an exception...
android.view.InflateException: Binary XML file line #29: Error inflating class RadioButton
Also I think I would need to specify the units i.e 'sp' in this case.
So is there a way to do it?
If not, i will probably have to set all text size's that need setting, programmatically.
Hopefully someone knows a better way.
inside dimens.xml, you can use the <dimen item, and specify the unit:
<dimen name="text_size_small">15sp</dimen>
to access it programmatically, you
textview.setTextSize(getResources().getDimension(R.dimen.text_size_small), TypedValue.COMPLEX_UNIT_PX);
in dimens the size is already scaled for the unit, so you don't need to apply the conversion again, hence the TypedValue.COMPLEX_UNIT_PX
In your dimens.xml specify your like this
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="text_size_small">15sp</dimen>
</resources>
In your layout use this
android:textSize="#dimen/text_size_small"
If you want to set this programtically, try like this
textview.setTextSize(getResources().getDimension(R.dimen.text_size_small));
You must define own textview style.
#styles
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="android:textViewStyle">#style/CMTextView</item
</style>
<style name="CMTextView" parent="android:style/Widget.TextView">
<item name="android:textSize">#dimen/text_size</item>
</style>
#dimens
<dimen name="text_size">18sp</dimen>

Action bar size in custom xml file

I'm not able to find a way to insert the action bar size attribute in my own xml file. Since I'm using Google maps in my activity, I can't use the built-in xml attribute at all in my layout, but I have to call setPadding() on the map using the action bar size. Now, I found the way to retrieve the actionBarSize at runtime, but I wonder if I could skip this code completly, inserting the android attribute in my onw xml, for example:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<dimen name="myownsize">#android:attr/actionBarSize</dimen>
</resources>
But in this way it doesn't work. Is there a way to do it?
Define a attr in your own project. Create res/values/attrs.xml and add this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myownsize" format="dimension"></attr>
</resources>
In your res/values/styles.xml, under your parent theme definition, initialize this attribute:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="myownsize">?android:attr/actionBarSize</item>
</style>
Once this is done, you can use ?attr/myownsize as a dimension:
android:padding="?attr/myownsize"
Sorry if I too, misunderstood the question.

Error when getting a dimension in theme for margins

Background
I'm trying to set a custom margin value on the listView items based on the selected theme.
The app has multiple themes, and the user can choose which theme to use , which I set by calling "setTheme()" .
The problem
whatever I try, I get this error:
java.lang.UnsupportedOperationException: Can't convert to dimension: type=0x2
note that this occurs only for the margin attribute, and so far no other attribute has caused this.
What I've tried
first, here's the xml snippets I've used
attrs.xml
<attr name="listview_item__horizontal_spacing" format="dimension" />
styles.xml
<style name="AppTheme_HoloDark" parent="#style/Theme.Sherlock">
<item name="listview_item__horizontal_spacing">4dp</item>
....
the layout of the listView item:
<RelativeLayout ...
android:layout_marginLeft="?attr/listview_item__horizontal_spacing" >
I've also tried using "reference" for the attribute type, and reference to a "dimen" resource, but it also cause the same exception.
Another thing I've tried is getting it dynamically:
public static int getResIdFromAttribute(final Activity activity,final int attr)
{
final TypedValue typedvalueattr=new TypedValue();
activity.getTheme().resolveAttribute(attr,typedvalueattr,true);
return typedvalueattr.resourceId;
}
...
final int spacingResId=getResIdFromAttribute(activity,R.attr.listview_item__horizontal_spacing);
but for some reason I get 0 as the result of this call. Only when using this method it worked.
The question
What is going on? How can I avoid this?
Is there really no way to overcome this but using code (when inflating the xml) ?
You don't need to use attr XML, and this is your issue.
Place your the value you want in a file named dimens.xml in your res folder (same location as strings.xml).
This file will look something like this:
<resources>
<dimen name="value1">15dp</dimen>
<dimen name="value2">20dp</dimen>
</resources>
Then in your layout XML, you can reference the dimen directly (just as you would reference a string), something like this:
<RelativeLayout ...
android:layout_marginLeft="#dimen/value1" >
or when defining a style, in your XML it would look like:
<style name="MyStyle1">
<item name="android:layout_marginLeft">#dimen/value1</item>
</style>
and then for your other style:
<style name="MyStyle2">
<item name="android:layout_marginLeft">#dimen/value2</item>
</style>

Android - how to set background color of all screens?

What is the best practice to maintain styles of fonts and colors. I made a colors.xml file which I have used to change colors on seperate elements like buttons, but I am not sure how Android wants developers to organize their styles.
For example, I would like all screens to have the same background color. How do I do that? Is it something I need to specify for each Activity layout xml? Or elsewhere? How do I accomplish it?
A quick and easy way to make sure every activity has the same background color, is to create a theme for your activities to use. That theme would specify the android:windowBackground.
First define the color in values/colors.xml
<resources>
<color name="background">#FF0000 </color>
</resources>
Create a themes.xml file in res/values that references that color:
<resources>
<style name="MyTheme" parent="#android:style/Theme.Light">
<item name="android:windowBackground">#color/background</item>
</style>
</resources>
... and then in your AndroidManifest.xml specify this as the theme for your activities to use.
<activity
android:name=".MyActivity"
android:theme="#style/MyTheme" />
Update your android studio to 1.4 it has inbuilt theme editor. as you can see in below image
You can also set the background at the application level in AndroidManifest.xml
<application
...
android:theme="#style/MyTheme">
(Note: I cannot this as a comment of the accepted answer as my reputation is too low).

Categories

Resources