What, when?
With the release of Android M (API 23) the Support library got a major update as well. One of the unsung heroes is a feature badly requested since Android’s early days – the ability to set dimensions in percentages. With the release of the Percent Support Library is’t now possible to set a View
to take exactly 30% of the screen, or to set it’s marginTop
to 10% for example.
How?
The Percent Support Library adds two new layout managers in the developers’ toolbox – PercentFrameLayout and PercentRelativeLayout. As their names suggest they derive from the well-known FrameLayout
and RelativeLayout
, with the extension that they support the new PercentLayoutHelper.PercentLayoutParams.
Using percents in your apps is easy:
1. Add a dependency in your build.gradle
file
compile 'com.android.support:percent:23.1.0'
2. Add one of the Percent layout managers to your layout
<android.support.percent.PercentRelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> </android.support.percent.PercentRelativeLayout>
3. Within this parent use the new percent attributes
<Button android:layout_height="wrap_content" android:text="50% width button" app:layout_widthPercent="50%" app:layout_marginTopPercent="10%" />
The list of allowed percent attributes is:
- layout_widthPercent
- layout_heightPercent
- layout_marginPercent
- layout_marginLeftPercent
- layout_marginTopPercent
- layout_marginRightPercent
- layout_marginBottomPercent
- layout_marginStartPercent
- layout_marginEndPercent
- layout_aspectRatio
All of those should be self-explanatory. The first two are substitutes for the standard android:layout_width/height
attributes. If you specify one of the new layout_widthPercent/heightPercent
, you do NOT need to specify the standard corresponding attribute.
The layout_aspectRatio
is interesting. It allows you to specify only one of the width / height and the other dimension will be automatically calculated based on the layout_aspectRatio
. Note that the ratio is always width:height. So:
- for
layout_width="100dp" app:layout_aspectRatio="50%"
the height will be200dp
- for
app:layout_aspectRatio="200%"
, height =50dp
The following pic illustrates this behavior.
Notes
Note 1: The developer docs say:
If you want the view to be able to take up more space than what percentage value permits, you can add
layout_width/height="wrap_content"
. In that case if the percentage size is too small for the View’s content, it will be resized usingwrap_content
rule.
This behavior was NOT working correctly with version 23.1.0
for me. Instead what I found out is that there’s strict priority of the attributes that’s followed.
app:layout_heightPercent
stronger than android:layout_height
stronger than app:layout_aspectRatio
.
So if more than one of those is specified for a View
, the system will only take into account the strongest of those.
Note 2: If you don’t specify any of the standard android:layout_width/heigh
, LINT will complain with a warning like the following:
As long as you’ve provided any of the “new” percent required attributes, the code will compile and run perfectly normal, but this warning can break builds configured to abort on lint errors. Unfortunately I couldn’t find a better solution so ended up suppressing the warnings manually when needed.
Conclusion
I created this simple GitHub project with more a few more examples. Check out the source if you want to solidify your understanding of the Percent Support Library.
I see this library making our lives easier when creating responsive layouts across variety of screen sizes. Another nice usage will be when dealing with ImageViews
, especially when we want them to be of certain dimensions. I’ll be happy if you leave a comment with your ideas of where this support library will be handy.
3 comments
Nadim GOUIA
8 years agohow can i set a negative margin right percent for an ImageView inside the PercentRelativeLayout ?
veskoiliev
8 years agoUnfortunately you can’t set negative percent margins 🙁 You can set negative solid dp margins, but that will most likely break the whole idea of using the Percent library in the first place. Perhaps you can rework your layout so that you don’t need the negative margin?
Scott
6 years agoI thought you would like to know, it looks like you’ve misspelled the word “dont” on your website. Silly mistakes can ruin your site’s credibility. In the past I’ve used a tool like SpellingScan.com to keep mistakes off my website.
-Scott Matthews Sr.