Mathematical operations in Android layout attributes - android

I need to use following otherwise my custom widget was overlapped by a Toolbar:
android:layout_marginTop="?android:attr/actionBarSize"
But I want to have additional margin, say 10dp. I cannot do something like:
android:layout_marginTop="?android:attr/actionBarSize + 10dp"
because + is not allowed character there. Is there any other way except coding a rule programmatically?

You could wrap your ViewGroup into another one just to add the 10dp margin. Not optimal but that would work.

Layout XML files do not support expressions. So You can't Perform exepression on it. You can perform in XSLT.
There is one trick describe below.
margin + padding as describe in this Answer.
Source : How do I apply mathematical operations to Android dimensions?

Related

How do i make the constraintlayout wrap my textview programmatically

I've got a problem and have no idea how to fix it. I'm using a ConstraintLayout in android
I want to set my TextView to wrap_content programmatically but respect my constraints.
Now the issue is that if i set my constriantWidth to WRAP_CONTENT it does not respect the constraints it's given to it.
I've found that there is a solution in xml in it here:
Wrap_content view inside a ConstraintLayout stretches outside the screen
but in this issue no where is it described how to set the property of constrainedwidth to true programmaticly.
I've tried a few things but have not found a solution to my problem:
set.constrainWidth(textView.getId(),ConstraintSet.WRAP_CONTENT)
just wraps the content without keeping in my constriants that i've set.
I've also tried to set the constraintedWidth with the ConstraintLayout.Params but nothing happend.
And i have no clue if en how i can set constrainedWidth in my ConstraintSet.
and
set.constrainWidth(textView.getId(),ConstraintSet.MATCH_CONSTRAINT_WRAP)
Just makes my text a thin line of my text and doesn't show my text anymore.
If someone could help i would be very great full.
PS. Sorry for my english not a native speaker.
Use constrainDefaultWidth:
set.constrainDefaultHeight(textView.getId(), ConstraintSet.MATCH_CONSTRAINT_WRAP);

What are insets in android?

I am beginner at android development. I was recently looking at someone else's code and found some functions view.onApplyWindowInsets(windowInsets), windowInsets.getSystemWindowInsetTop(). And this word was used frequently in the same app.
I tried googling it and found InsetDrwable class with explanation
A Drawable that insets another Drawable by a specified distance. This is used when a View needs a background that is smaller than the View's actual bounds.
Can some one explain me what is the meaning on Insets and what those piece of code up there meant?
A explanation with an example will be appreciated.
Suppose you have a TextView and you need to add a background to the TextView. But, on the other hand, you don't want the background to scan the entire View (TextView), therefore, you need to use Insets.
A Drawable that insets another Drawable by a specified distance or
fraction of the content bounds. This is used when a View needs a
background that is smaller than the View's actual bounds.
The background can be a Drawable. Hence you need to use the <inset> attribute inside your xml file (activity_main.xml) "For Example".
Then, after using the <inset> tag, you can specify some attributes such as:
<inset
android:drawable="#drawable/(Enter the file name under drawable)"
android:insetBottom="4dp"
android:insetTop="4dp"/>
For more information please have a look at InsetDrawable on Android developer.com
Hope this helps!

How to set default Android padding to an element without padding?

Let's say I just added two standard widgets -- CheckBox and CheckedTextView. The first one has nice, clear padding despite that fact I didn't set any, and there is no padding set in .xml file. The other one comes without any padding.
Now, I could get the value (fixed) of the padding from CheckBox by trial&error. But my question is how to set it in kind of dynamic fashion -- i.e. if in Android 7.0 padding for CheckBox will be "20sp" and I set "10sp" (because it is now 10sp -- I am making this up) then my two widgets would be with different paddings.
And I would like to have a consistent padding. So how to set something like "?android/default_padding" for padding?
Clarification: I am interested in using the system default padding, not hardcoding the same value made up by me over all widgets.
I looked it up for you, in API Level 10 (and also on every other Android platform) Android uses 9-Patch images with prefdefined paddings (there is no padding declared in the Selector), e.g. I mesured the checkbox and it as this pasddings: left, right: 6dp; top, bottom: 12dp. And the default button has a padding of 10dp; so there is no default padding as far as I can tell. But 10dp is good in most cases. Also, it just really depends on the screensize of your device. You will have to declare your own prefered padding like Daniel suggested. E.g: In your Values file 10dp and in values-large maybe 15.
Edit:
Here is the default checkbox for mdpi on Android 2.3.3:
You could create in your resources an xml file called dimens.xml, and the add something like this:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<dimen name="default_padding">10dp</dimen>
</resources>
Then you call from your layout something like this:
android:padding="#dimen/default_padding"
I think this is a consistent way of working :)
Good Luck!!!

Android layout reusing, is "exporting" properties possible?

I am developing an application where certain elements will repeat themselves a lot over the whole interface. Googling a bit i found out about the <include /> tag, which is working nicely for what i want.
I was just wondering if there is a way to export certain properties of the included layout: One of them has an image and a string that change according to the use case, and i'd like to set these in the XML file for each case, instead of having to write boilerplate code to set them in the code; Is there any way to do this? Or am i doomed to write that code?
We're all doomed. As explained in the article Creating Reusable Components, the only things that you can override are the layout_* attributes and the id. There's no way (sadly) to parameterize a layout like you describe.
The <include> tag is is useful for separating configuration-dependent parts of your layout from those parts that are invariant across devices. (E.g., you can <include layout="#layout/footer"> and have different footer.xml files for different configurations.)

Defining Z order of views of RelativeLayout in Android

I would like to define the z order of the views of a RelativeLayout in Android.
I know one way of doing this is calling bringToFront.
Is there are better way of doing this? It would be great if I could define the z order in the layout xml.
The easiest way is simply to pay attention to the order in which the Views are added to your XML file. Lower down in the file means higher up in the Z-axis.
Edit:
This is documented here and here on the Android developer site. (Thanks #flightplanner)
If you want to do this in code
you can do
View.bringToFront();
see docs
Please note, buttons and other elements in API 21 and greater have a high elevation, and therefore ignore the xml order of elements regardless of parent layout. Took me a while to figure that one out.
In Android starting from API level 21, items in the layout file get their Z order both from how they are ordered within the file, as described in correct answer, and from their elevation, a higher elevation value means the item gets a higher Z order.
This can sometimes cause problems, especially with buttons that often appear on top of items that according to the order of the XML should be below them in Z order. To fix this just set the android:elevation of the the items in your layout XML to match the Z order you want to achieve.
I you set an elevation of an element in the layout it will start to cast a shadow. If you don't want this effect you can remove the shadow with code like so:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
myView.setOutlineProvider(null);
}
I haven't found any way to remove the shadow of a elevated view through the layout xml.
I encountered the same issues: In a relative layout parentView, I have 2 children childView1 and childView2. At first, I put childView1 above childView2 and I want childView1 to be on top of childView2. Changing the order of children views did not solve the problem for me. What worked for me is to set android:clipChildren="false" on parentView and in the code I set:
childView1.bringToFront();
parentView.invalidate();
Please note that you can use view.setZ(float) starting from API level 21. Here you can find more info.
Thought I'd add an answer since the introduction of the
android:translationZ
XML field changed things a tad. The other answers that suggest running
childView1.bringToFront();
parentView.invalidate();
are totally spot on EXCEPT for that this code will NOT bring childView1 in front of any view with a hardcoded android:translationZ in the XML file. I was having problems with this, and once I removed this field from the other views, bringToFront() worked just fine.
API 21 has view.setElevation(float) build-in
Use ViewCompat.setElevation(view, float); for backward compatibility
More methods ViewCompat.setZ(v, pixels) and ViewCompat.setTranslationZ(v, pixels)
Another way collect buttons or view array and use addView to add to RelativeLayout
childView.bringToFront() didn't work for me, so I set the Z translation of the least recently added item (the one that was overlaying all other children) to a negative value like so:
lastView.setTranslationZ(-10);
see https://developer.android.com/reference/android/view/View.html#setTranslationZ(float) for more
Or put the overlapping button or views inside a FrameLayout. Then, the RelativeLayout in the xml file will respect the order of child layouts as they added.
You can use custom RelativeLayout with redefined
protected int getChildDrawingOrder (int childCount, int i)
Be aware - this method takes param i as "which view should I draw i'th".
This is how ViewPager works. It sets custom drawing order in conjuction with PageTransformer.
Check if you have any elevation on one of the Views in XML. If so, add elevation to the other item or remove the elevation to solve the issue. From there, it's the order of the views that dictates what comes above the other.
You can use below code sample also for achieving the same
ViewCompat.setElevation(sourceView, ViewCompat.getElevation(mCardView)+1);
This is backward compatible.
Here mCardView is a view which should be below sourceView.

Categories

Resources