写了那么多Android布局,你知道elevation属性吗
转自: https://www.jianshu.com/p/c1d17a39bc09
一、elevation
我们知道,在RelativeLayout里面,或者更加纯净的FrameLayout里面,后写的View会覆盖之前写的View上面。
比如:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#ff0000"
>
<View
android:id="@+id/vGeeen"
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#00ff00"/>
<TextView
android:id="@+id/vBlue"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#0000ff"/>
</RelativeLayout>
</RelativeLayout>
效果
嗯,这很正常,vBlue现在vGeeen之上,一切很正常。
这时候,主角elevation登场。
我们稍加改动,给vBlue加上一行代码:android:elevation="1dp"
即现在代码变成:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:background="#ff0000"
>
<View
android:id="@+id/vGeeen"
android:layout_width="200dp"
android:layout_height="200dp"
android:elevation="1dp"
android:background="#00ff00"/>
<TextView
android:id="@+id/vBlue"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#0000ff"/>
</RelativeLayout>
</RelativeLayout>
在看看现在的效果:
我的mBlue哪去啦,说好的最后出场的都是主角呢,mBlue居然不见啦!
我们知道,在css里面,我们经常会计算权重,在刚刚的实践里面,加了mGreen加了android:elevation="1dp",相当于在这些View里面他的权重提高了,升官啦!
在android的世界里面,elevation起到了权重的作用,而且,每一个View的默认权重都是0dp,但在Google说他是一个阴影的作用,但是实际上由于MD设计的高度Z造成的,后面我会说到
如果我们把上面的mGreen的把elevation设置为android:elevation="0dp",那么一切照旧,最后出场的mBlue依然会覆盖着mGreen。
原来,这个elevation是2014 年,Google 推出了Material Design新的 Android 支持库 v7之后才有的产物(但是过了这么久我都没用过elevation属性,惭愧)
那为什么elevation可以起到类似权重的作用呢?
因为,在MD设计里面,视图可以投射阴影, elevation 值决定了阴影的大小和顺序。要设定 elevation 值
我们来新建一个布局,给TextView设置android:elevation="30dp",看看会产生什么效果
设置
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="#000000"
android:layout_centerInParent="true"
android:elevation="30dp"
/>
</RelativeLayout>
通过上图已经很说明了情况。
二、Material Design 之高度视图高度 Z
在Material Design主题当中给UI元素引入了高度的概念,视图的高度由属性Z来表示,决定了阴影的视觉效果,Z越大,阴影就越大且越柔和。但是Z值并不会影响视图的大小。
视图的Z值由两个分量表示:
- 1、Elevation:静态的分量
- 2、Translation:用于动画的动态的分量
Z值的计算公式为:
Z=elevation+translationZ
elevation属性和translationZ是好朋友。
具体我们就不在这里细说了,具体了解可以查阅Material Design中的Elevation和shadows,写的挺好的。
三、缘从何时起
那么,这个elevation属性我是如何发现的。
一切都要从CardView说起。
我们经常会在CardView里面设置类似app:cardElevation="5dp"
之类的代码。
然后就是我发现处于CardView底部一个View死活不出来,app:cardElevation就是
CardView独有的elevation,当然了,CardView也是可以设置elevation的。
小结一下:
MD设计中,视图有高度的概念,用Z来表示,Z受到Elevation和Translation两个量控制,因为这个高度的概念,导致了elevation属性产生了类似css中的权重的作用。