Based on here on XML Attributes section I specify following in my dimens.xml:
<dimen name="match_parent">-1dp</dimen>
<dimen name="main_left_menu_user_account_width">#dimen/match_parent</dimen>
<dimen name="main_left_menu_user_account_height">#dimen/match_parent</dimen>
Then I use the both dimensions in my layout:
<ImageView
android:id="#+id/userAccountImage"
android:background="#drawable/user_account"
android:layout_width="#dimen/main_left_menu_user_account_width"
android:layout_height="#dimen/main_left_menu_user_account_height" />
Then, when I preview to Graphical Layout, it complains:
You must supply a layout_width attribute.
You must supply a layout_height attribute.
Actually can I define a value equals to match_parent in dimens.xml?
Update:
I also tried this but the preview still complains:
<dimen name="main_left_menu_user_account_width">-1dp</dimen>
<dimen name="main_left_menu_user_account_height">-1dp</dimen>
I successfully use wrap_content (the Graphical Layout doesn't complain at all):
<dimen name="wrap_content">-2dp</dimen>
<dimen name="main_right_menu_width">#dimen/wrap_content</dimen>
<dimen name="main_right_menu_height">#dimen/wrap_content</dimen>
Use this, it works for me
<dimen name="custom_wrap_content">-2px</dimen>
<dimen name="horizontal_border_height">#dimen /custom_wrap_content</dimen>
<dimen name="custom_match_parent">-1px</dimen>
<dimen name="vertical_border_height">#dimen /custom_match_parent</dimen>
And the Reason why match_parent doesn't run. You cannot supply a build in keyword like match_parent
Edit: Use px instead of dp as suggested by Jarett Millard in the comments.
First create attribs.xml:
<resources>
<item name="match_parent" type="dimen">-1</item>
<item name="wrap_content" type="dimen">-2</item>
</resources>
Second use your dimens:
<dimen name="account_width">#dimen/match_parent</dimen>
<dimen name="account_height">#dimen/wrap_content</dimen>
Depending on why you want to define match_parent in a #dimen, this use case could help you:
Instead of defining the width and height in dimen.xml, you can define it as a style in the styles.xml
I use
//res/values/styles.xml
<style name="IntroLayout">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>
and
//res/values-sw600dp/styles.xml
<style name="IntroLayout">
<item name="android:layout_width">520dp</item>
<item name="android:layout_height">wrap_content</item>
</style>
and use it like
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_gravity="center"
style="#style/IntroLayout">
which allows me to dynamically set the width and height attributes for different sized devices without having to write any code and you can use match_parent/wrap_content fine. you can use any #dimen that you have defined previously in the style as well if you want.
I use this because the layout for phone and tablet is the same, except i want to fix the width on tablet but fill the parent on phone, so it saves having to have 2 different layouts with basically the same xml
For HTC devices use this to achieve match_parent:
<dimen name="my_match_parent">-1.0px</dimen>
You can also achieve this using integers.xml file
integers.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="match_parent">-1</integer>
<integer name="wrap_content">-2</integer>
</resources>
Use in dimens.xml:
<dimen name="main_right_menu_width">#integer/wrap_content</dimen>
You might also get lint warning, to suppress it use:
<dimen name="main_right_menu_width" tools:ignore="ReferenceType">#integer/wrap_content</dimen>
I don't think so. #dimen/match_parent is a specific length with unit while match_parent is a special flag.
Related
In my Android app, I use LinearLayout's weight at multiple point in my app. Those weight are both used in xml and in code as I change them dynamically.
To reuse the same values everywhere, I thought I could declare them in my dimens.xml file like this:
<resources>
<dimen name="total_weight">5</dimen>
<dimen name="expanded_weight">3</dimen>
<dimen name="collapsed_weight">2</dimen>
</resources>
But it doesn't work as dimen only accept dp, px or sp units.
What workaround could I use?
you can use
<?xml version="1.0" encoding="utf-8"?>
<resources>
<integer name="integer_name">0</integer>
</resources>
access by
resources.getInteger(R.integer.integer_name)
you can take a look at https://developer.android.com/guide/topics/resources/more-resources
I have a lyaout and I want to change its constraints in phone vs. tablet.
I want to set the top_toTop to be in relate to viewA while in phone device
app:layout_constraintTop_toTopOf="#+id/viewA"
And I want it to relate to the aprent while in tablet device
app:layout_constraintTop_toTopOf="parent"
I thought to use resource referencing but how do i reference to the parent? it's not a resource
Option 1
Instead of using parent you can use the id of the parent view (the ConstraintLayout itself), this way you could swap just the id with a configuration-specific resource. Say your layout looks like this:
<android.support.constraint.ConstraintLayout
android:id="#+id/rootView"
...
>
<View
android:id="#+id/someView"
...
/>
<View
...
app:layout_constraintTop_toTopOf="#id/myAnchorView"/>
</android.support.constraint.ConstraintLayout>
You can then define 2 different id references in your configuration, say phone:
<resources>
<item name="anchorView" type="id">#id/rootView</item>
</resources>
And tablet:
<resources>
<item name="anchorView" type="id">#id/someView</item>
</resources>
Option 2
Define a style for your view and have 2 versions of that style, one for phone:
<style name="MyView">
<item name="layout_constraintTop_toTopOf">parent</item>
</style>
and one for tablet:
<style name="MyView">
<item name="layout_constraintTop_toTopOf">#+id/viewA</item>
</style>
the code you have app:layout_constraintTop_toTopOf="parent" is correct but you have to put in the correct layout folder
you could also create 2 dimens files with the ids
phone
<resources>
<dimen name="view_parent">#id/viewA</dimen>
</resources>
tablet
<resources>
<dimen name="view_parent">#id/parentId</dimen>
</resources>
layout
app:layout_constraintTop_toTopOf="#dimen/view_parent"
How can i define the match_parent flag in a dimens.xml?
<dimen name="width">match_parent</dimen>
I tried the methods here Value equals to match_parent or fill_parent in dimens.xml? but none work.
Iam using Android > 27 API.
First create attribs.xml:
<resources>
<item name="match_parent" type="dimen">-1</item>
</resources>
Second use your dimens:
<dimen name="account_width">#dimen/match_parent</dimen>
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>
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"