How to use different percent values for guidelines in ConstraintLayout? - android

I use constraint layout in my activity and I would like to set different percent values for my guidelines (app:layout_constraintGuide_percent="0.5"). I want to put this values to different dimens files (dimens-lands, dimens-sw600dp etc.) The problem is that I can't find any way how to put this percent value to dimens.xml. Is there any way how to keep different percent values for multiple screens in my res/? This is how percents are declared - it is a float value:
<android.support.constraint.Guideline
android:id="#+id/center_guideline"
style="#style/Layout.Guideline"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />

The answer above does not work. It does not even show up in autocomplete when typing there app:layout_constraintGuide_percent="..."
Tried cleaning and rebuilding as well. Still no luck. Weird that it worked for you.
EDIT: What worked is changing the type from dimen to integer :
<item name="some_percentage" type="integer" format="float">0.6425</item>

In the end I found out a way how to store value with decimal point (float) in res/values. It must be stored this way:
<resources>
<item format="float" name="guideline_right" type="dimen">0.84</item>
</resources>

Related

Android Studio reset my #dimen in xml

I have some problem with setting params to my view in xml file with values from dimen files.
For example when i'm adding layout_height param to my EditText in laytout xml file:
<EditText
....
android:layout_height="#dimen/et_height"
....
/>
File dimens:
<resources>
.........
<dimen name="example">16dp</dimen>
<dimen name="et_height">20dp</dimen>
.........
</resources>
It works fine. But sometimes when i open this file again AndroidStudio replace #dimen/et_height with value 20dp in layout xml file. And i must change it again to #dimen/et_height.
How can i fix this ?
This is the normal case:
But in my case AndroidStudio replaces with value:
Having the same issue. Thought it is the ConstraintLayout but the issue also appears in every other layout though..
related post from me :
Android ConstraintLayout #dimens replaced with hardcoded values
Also some other user said it just shows the dp value, i am completely in your situation i know the grey text, but it does really replace the value..

Android Layout: use dimen just for some resolution

I'm trying to have an image which preserves its size in all the resolution except one... what i would like is to use the "wrap_content" attribute for height and override it with a dimen attribute but just for a particular case (like values-xlarge). I did like this:
<ImageView android:id="#id/image_frame"
android:layout_width="match_parent"
android:layout_height="#dimen/overlayImageHeight" />
But of course it crashes if i don't define the overlayImageHeight in all the dimen.xml files.
I tried to put a "wrap_content" string for other dimen.xml files but again it fails since dimen files just accept numeric values inside.
Is there a way to define this behaviour inside an xml file? Other way to do it programmatically?
Any help appreciated!
You should give it a style, define the style in res/values/styles.xml, then make a different version of the style in res/values-xhdpi/styles.xml.

usage of resources in layout

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

Android - how do you manage multiple layout files in line with DRY principle?

To support different resolutions, we need to make variations of layout files as described in Supporting Multiple Screens very well. Assuming you don't plan to show different arrangement of your UI but just want to stretch appropriately, your variations would be mostly about different weights. At least that is the case with my app so far.
Now, how do you manage changing the application with this structure? Since it repeats the layout many times, one layout change in your application causes multiple files change.
I thought of two options:
Changing the values dynamically in your code
Downside is your layout related work is spilled over to the code. I really don't like this.
Making child layout to extract common layout elements
Downside is your layout's hierarchy will be deeper and cluttered so it would be harder to figure out what's going on. Still, this is better than option #1 thanks to Hierarchy Viewer. I am not sure if this approach will be always achievable.
If you could share your tricks to get through this, it would be much appreciated.
I think I found a solution. I will accept it as an answer if others give thumbs up.
I found Configuration qualifiers described in Supporting Multiple Screens works not only for res/drawable and res/layout but also for res/values. So on my layout/some_layout.xml, I say like this:
<ImageButton
android:id="#+id/imagePlay"
android:layout_width="#dimen/button_size"
android:layout_height="#dimen/button_size"
android:scaleType="fitCenter"
android:src="#drawable/play" />
Then on values/layout.xml file you define the default button_size:
<resources>
<dimen name="button_size">44dp</dimen>
</resources>
And on values-xlarge/layout.xml file you define the xlarge mode button_size:
<resources>
<dimen name="button_size">66dp</dimen>
</resources>
I didn't try other values resources, but I assume it also works for Styles and Themes so in case your layout customization is a little bit more than a size or weight, you could define a style in the values and use it.

Usage of TypedArray in Android Application

I came across code at
HelloGallery Example
ImageAdapter.java - http://developer.android.com/resources/tutorials/views/hello-gallery.html
TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery);
mGalleryItemBackground = a.getResourceId(
R.styleable.HelloGallery_android_galleryItemBackground, 0);
a.recycle();
attrs.xml - http://developer.android.com/resources/tutorials/views/hello-gallery.html
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="HelloGallery">
<attr name="android:galleryItemBackground" />
</declare-styleable>
</resources>
and also code at :
Snake Game Example
TileView.java - http://developer.android.com/resources/samples/Snake/src/com/example/android/snake/TileView.html
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView);
mTileSize = a.getInt(R.styleable.TileView_tileSize, 12);
a.recycle();
attrs.html - http://developer.android.com/resources/samples/Snake/res/values/attrs.html
<resources>
<declare-styleable name="TileView">
<attr name="tileSize" format="integer" />
</declare-styleable>
</resources>
May I know why they need to get the integer value from XML? Why don't they just code mGalleryItemBackground = 0; and mTileSize = 12;? My guess is that, they want to able to change something without touching Java code. But, I do not see any value being specified explicitly in the XML file itself. A code example to demonstrate the purpose of TypedArray and context.obtainStyledAttributes is very much appreicated.
Both are trying to read an integer. Why one of the example is using getResourceId technique, another is using getInt technique?
I refer to TypedArray JavaDoc, but I can hardly understand what recycle does?
Give back a previously retrieved
StyledAttributes, for later re-use.
May I know why they need to get the integer value from XML? Why don't they
just code mGalleryItemBackground = 0;
and mTileSize = 12;?
I think it's mainly to demonstrate the technique of reading XML attributes from the View constructor, rather than to meet an absolute requirement. If you wanted to re-use your custom view elsewhere (not terribly likely for something as specific as Snake I'll admit) then this is a fantastically useful thing to be able to do... to change the backgound colour etc without having to touch the Java code.
For the tile size in particular, that might be useful to read from XML in case there are different layouts for different device types... you might want different size tiles for different density+size combinations.
Both are trying to read an integer. Why one of the example is using
getResourceId technique, another is
using getInt technique?
Because the gallery background isn't an integer... it's expected to be a resource identifier (such as #drawable/foo). Yes it is still an integer, but an integer whose value isn't known until runtime. The tile size, by contrast, is a constant value and doesn't require any kind of runtime resolving.
I refer to TypedArray JavaDoc, but I can hardly understand what recycle
does?
If in doubt, look at the source. It's basically an optimization to avoid the LayoutInflater having to allocate one of these for every view it inflates.
About styleable attributes
In addition to being able to change that value without touching Java code, it allows them to apply different styles to their app depending on device configuration. Instead of declaring in XML:
<com.example.android.snake.SnakeView
android:id="#+id/snake"
android:layout_width="match_parent"
android:layout_height="match_parent"
tileSize="24" />
they can declare these values in res/values/styles.xml:
<style name="Control.SnakeViewStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="tileSize">24</item>
</style>
and then refer to that style:
<com.example.android.snake.SnakeView
android:id="#+id/snake"
style="#styles/SnakeViewStyle" />
After separating styles like this they can provide different styles.xml file for each device configuration. For example, there might be one res/values/styles.xml for portrait mode and one res/values-land/styles.xml for landscape mode.
About resources and integers
If a styleable attribute is declared as "reference" instead of "integer", you would (1) get IDE content assist when writing XML for that attribute and (2) compiler would check that you haven't provided a reference to non-existing resource. Consequently, to get it you need to use getResourceId, because it may do some additional resolving to get actual resource id.
About recycle
I'm not really sure, but judging by the code of TypedArray, it seems that there's some caching mechanism inside it, and recycle() makes it work.

Categories

Resources