I was wondering if it is possible to make a dimension a multiple of another dimension in Android. E.g., so I can do something like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="base">50dp</dimen>
<dimen name="size_of_something">4*#dimen/base</dimen>
</resources>
Right now, I use a workaround like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="base_x1">50dp</dimen>
<dimen name="base_x2">100dp</dimen>
<dimen name="base_x3">150dp</dimen>
<dimen name="base_x4">200dp</dimen>
<!-- etc... -->
<dimen name="size_of_something">#dimen/base_x4</dimen>
</resources>
But this means that I have to update all the multiples every time I change the base size, which is not only cumbersome, but also error-prone.
Related
In material design 3, there are 15 types of typography tokens:
textAppearanceDisplayLarge (57sp)
textAppearanceDisplayMedium (45sp)
textAppearanceDisplaySmall (36sp)
textAppearanceHeadlineLarge (32sp)
textAppearanceHeadlineMedium (28sp)
textAppearanceHeadlineSmall (24sp)
textAppearanceTitleLarge (22sp)
textAppearanceTitleMedium (16sp)
textAppearanceTitleSmall (14sp)
textAppearanceBodyLarge (16sp)
textAppearanceBodyMedium (14sp)
textAppearanceBodySmall (12sp)
textAppearanceLabelLarge (14sp)
textAppearanceLabelMedium (12sp)
textAppearanceLabelSmall (11sp)
Here is how I used the tokens:
values\dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="textSizeDisplay">36sp</dimen>
<dimen name="textSizeHeadline">24sp</dimen>
<dimen name="textSizeTitle">14sp</dimen>
<dimen name="textSizeBody">12sp</dimen>
<dimen name="textSizeLabel">11sp</dimen>
</resources>
values-large\dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="textSizeDisplay">45sp</dimen>
<dimen name="textSizeHeadline">28sp</dimen>
<dimen name="textSizeTitle">16sp</dimen>
<dimen name="textSizeBody">14sp</dimen>
<dimen name="textSizeLabel">12sp</dimen>
</resources>
values-xlarge\dimens.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="textSizeDisplay">57sp</dimen>
<dimen name="textSizeHeadline">32sp</dimen>
<dimen name="textSizeTitle">22sp</dimen>
<dimen name="textSizeBody">16sp</dimen>
<dimen name="textSizeLabel">14sp</dimen>
</resources>
Depending on the text type, I use the tokens
<com.google.android.material.textview.MaterialTextView
...
android:textSize="#dimen/textSizeTitle" />
The question:
Did I use the tokens in the right way or there is another way to use the tokens?
Also, I know when I should use Display and Body, But when should I use Headline, Title, and Label because I think they are the same?
I read this and this but still don't know when should I use Headline, Title, and Label.
Thank you.
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 been overriding the space between my menu icons and menu text for sometime now but, when I migrated to androidx the override seems to be no longer working. Any idea on how to override them on androidx?
Here is my current override on dimens.xml
<dimen tools:override="true"name="design_navigation_icon_padding">10dp</dimen>
<dimen tools:override="true"name="design_navigation_icon_margin">5dp</dimen>
Here you can find the attributes used in the new NavigationView in the Material Components for Android library.
<dimen name="design_navigation_max_width">280dp</dimen>
<dimen name="design_navigation_elevation">16dp</dimen>
<dimen name="design_navigation_item_icon_padding">32dp</dimen>
<dimen name="design_navigation_item_horizontal_padding">16dp</dimen>
<dimen name="mtrl_navigation_elevation">0dp</dimen>
<dimen name="mtrl_navigation_item_icon_padding">14dp</dimen>
<dimen name="mtrl_navigation_item_icon_size">24dp</dimen>
<dimen name="mtrl_navigation_item_horizontal_padding">22dp</dimen>
<dimen name="mtrl_navigation_item_shape_horizontal_margin">8dp</dimen>
<dimen name="mtrl_navigation_item_shape_vertical_margin">4dp</dimen>
However the best way to change these values is to use the xml attributes like itemIconPadding in the layout.
Something like:
<com.google.android.material.navigation.NavigationView
...
app:itemIconPadding="#dimen/myvalue"/>
You can use new material NavigationView with app:itemIconPadding:
<com.google.android.material.navigation.NavigationView
...
app:itemIconPadding="#dimen/navigation_icon_padding"/>
dimens.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="navigation_icon_padding">12dp</dimen>
</resources>
When I add the file dimens.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="smart_eyeglass_controll_width">419</dimen>
<dimen name="smart_eyeglass_controll_height">138</dimen>
</resources>
to my values folder, R will not be generated.
What is wrong?
The file is OK - the rest of the project to. Cleaning the project up in Eclipse won't work.
Why it Showing
Because there are some compile error (or bug?) regarding to the xml file in res, so R is not genetared .
So,basically just Add unit beside your dimen value Like dp
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="smart_eyeglass_controll_width">419dp</dimen>
<dimen name="smart_eyeglass_controll_height">138dp</dimen>
</resources>
Then rebuild and clean your project
because you can't create dimens whiteout indicating that whether its a dip or sp or... if you want to create an integer value use:
<integer name="something">100</integer>
and if it has a unit put it..
<dimen name="width">100dip</dimen>
you have to specify an unit for your value, such dp. E.g
<resources>
<dimen name="smart_eyeglass_controll_width">419dp</dimen>
<dimen name="smart_eyeglass_controll_height">138dp</dimen>
</resources>
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.