I'm using API 19, and I have the following shadow showing up over my DrawerLayout in newer versions of android (API 22 for example).
Screenshot
I want it gone, and I can't figure out how to achieve this.
What I've tried so far:
Setting elevation on literally every element to 0dp in the XML,
setting the elevation programatically for the DrawerLayout and Toolbar using getSupportToolbar(),
setting the shadow to an empty Drawable,
adding various other settings in style XML with no result.
For my case just removed the line from the parent layout and the problem have solved!
android:fitsSystemWindows="true"
By the way, I have also tried all the solution I have known! But there is no solution until I removed "android:fitsSystemWindows" attribute from the parent layout. Hope this will help who will suffer the same problem. Thanks.
I'm working with material design and I faced the problem I can't solve. It's about the shadows/elevation.
Here we can read about the shadows and elevations in Material Design
https://developer.android.com/training/material/shadows-clipping.html#Shadows
But we can use these features only in lollipop and higher.
And what about the pre-lollipop devices? If I want to create the app which could be used at pre-lollipop devices then I can't use, for example
android:elevation="2dp"
Am I right?
If so then all I can do - it's using the design drawables which already include their shadows.
And here's another issue that I can't get.
For example, the designer gives me psd with some design. Imagine it looks like this
As you can see, top margin of the panel is 448px. We can easily get this margin value using the Photoshop.
But when I extracted this panel with its shadow then I discover that shadow by itself takes 10 px at the top of the panel
That 448px top margin doesn't count the shadow.
Obviously I can't just put panel.png on my some_layout.xml and set the margin top as 448px(298.67dp) because this drawable includes the shadow. It seems I should consider the shadow length and I should deduct this length from the top margin (448-10=438px=292dp).
Is this reasoning correct? I just can't believe it. This way seems to be too complicated. Maybe more effective practice exists?
According to shadow in Pre Lollipop devices
For Android 5.0 and above : AppBarLayout automatically provides/gives
shadow in the layout. You can also increase the elevation of the
AppBarLayout by android:elevation="4dp"
For Pre-Lollipop : You can use the following link:
http://blog.grafixartist.com/add-a-toolbar-elevation-on-pre-lollipop/
Note: Toolbar also supports elevation to it, using
android:elevation="4dp"
Read more: Add elevation/shadow on toolbar for pre-lollipop devices
According to elevation in Pre Lollipop devices
You can't mimic the elevation on pre-Lollipop with a official method.
You can use some drawables to make the shadow in your component.
Google uses this way in CardView for example.
The ViewCompat.setElevation(View, int) currently creates the shadow
only on API21+. If you check the code behind, this method calls:
API 21+:
#Override
public void setElevation(View view, float elevation) {
ViewCompatLollipop.setElevation(view, elevation);
}
API < 21
#Override
public void setElevation(View view, float elevation) {
}
Read more: How to implement the Material-design Elevation for Pre-lollipop
EDIT: As #geek90 suggest visit also this repo: http://github.com/navasmdc/MaterialDesignLibrary
It frustrated me too. I didn't like making shadows with gradients. I dove into the documentation, found how is the Lollipop's implementation done and coded that from scratch for older devices.
My implementation is called Carbon. It's a Material Design implementation with support for dynamic, automatic shadows. No need to add any kind of margin or gradient - just specify elevation for a view and get shadows on all SDKs.
https://github.com/ZieIony/Carbon
Read more about the method here: How to implement the Material-design Elevation for Pre-lollipop
I'm trying to set a shadow on my navigation drawer after updating the support library but for some reason nothing is working and I'm stumped.
I came across this issue but it's solution is to just use setElevation which is also not working for me: https://code.google.com/p/android/issues/detail?id=184434
There really isn't much code to post but here's what I'm talking about for reference:
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP) {
mDrawerLayout.setDrawerElevation(25f);
} else {
mDrawerLayout.setDrawerShadow(R.drawable.left_drawer_shadow, GravityCompat.START);
}
I'm using a ScrimInsetsFrameLayout but that shouldn't be causing the issue AFAIKT.
Any ideas?
What might have happened:
Since support lib 23 v21+ devices ignore custom drawables in this case. The the native built in elevation shadows are used. See: this issue
Here is the kicker though: transparent elements have no shadow.
By default the elevation shadow is drawn from the views background-outline. If the view has no background, the shadow won't show up.
If your view doesn't have its own background, using the outline Provider e.g.:
android:outlineProvider="bounds"
should do the trick. The doc can be found here ViewOutlineProvider.
In short:
Interface by which a View builds its Outline, used for shadow casting and clipping.
Some more information and in-depth explanation is here: Android "elevation" not showing a shadow
In my application I use a ListView and I need to remove the cacheColorHint at the bottom and top of the list. I tried to set the cacheColorHint to #00000000 but the have semi-transparent effect at the bottom/top.
Do you if it is possible to remove these effect?
Thanks
I think the problem is not with cacheColorHint. Maybe you are trying to deal with fading edge attribute of the listview.
Add this attribute to your listview and check it out,
android:fadingEdge="none"
EDIT
This attribute is deprecated and will be ignored as of API level 14 (ICE_CREAM_SANDWICH). Use android:fadingEdgeLength="0dp" instead. (from Zsolt Safrany's comment).
Take a look at this great article of Romain Guy: http://www.curious-creature.org/2008/12/22/why-is-my-list-black-an-android-optimization/
However to disable the optimization, simply use the transparent color #00000000 for the cacheColorHint, as you are doing, and set a solid background color on the ListView to replace its default semi-transparent background.
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.