如果我们想要打造更好的AndroidApp,相信需要遵循MaterialDesign的设计规范。总的来说,MaterialDesign是一个包含灯光、材质和阴影的三维环境。如果我们想在App开发过程中遵循MaterialDesign的设计原则,理解光影尤为重要。我将尝试在本文中解释以下主题。Android中的3D深度Z轴、高程和平移Z。LightsButton状态(按下和静止)OutlineCustomViewOutlineProvider在深入研究阴影和光照之前,我想告诉你关于我们真实环境的什么?什么是3D?真实的物理环境是一个三维空间,也就是说所有的物理对象都有X、Y、Z维度。Z轴垂直于显示器平面对齐,正Z轴朝向观察者延伸。在MaterialDesign的世界里,每个对象的厚度都是1dp。Android的DepthMaterialDesign不同于其他的设计指南,因为它加入了Depth(深度)的概念。而Depth在realvision中有着重要的意义。我们可以认为我们的桌子上有一层纸,再贴一张纸,我们的眼睛就会觉得它有深度。让我们用MaterialDesign应用程序屏幕截图来形象化它。让我们来看看屏幕上的各种元素。Screen(Surface-Depth0)CardViewsAppUILayout浮动操作按钮(FloatingActionButton)在这里,每个元素都在另一个元素之上。CardView是可滚动的,所以我们可以说第一层是可滚动的内容,第二层是AppBar布局,第三层(顶层)是浮动操作按钮。那么,我们如何定义等级呢?我们如何让用户感受到深度?答案是:Z轴。Android中的Z值是多少?View的Z值有两个组成部分:Elevation:高度,一个静态值。TranslationZ:Z轴变化值,用于动画的动态值。我一直想知道Elevation和TranslationZ有什么区别。Elevation是静态的,所以你不能动态改变它。如果要在Z轴上设置动画效果(例如按下状态或静止状态),则需要使用TranslationZ属性。TranslationZ是动态的,当你创建一个空白项目并向其添加一个按钮时,当你按下它时你会看到阴影变大。实际上Elevation并没有改变,但是TranslationZ属性在改变。这是Android使用默认状态列表动画,更改Z属性。ZVaue=Elevation+TranslationZ如果我们改变两个View的Z值,让它们相交。Android如何处理屏幕上的图层?让我给你看我设计的图表。另一个问题,我们如何看到物体的影子?我们需要影子吗?不,我们需要一个光源。Android中的光源是什么?其实问题不在于什么?但是哪里。实际上,如果我们拿着手电筒(从上面)照在桌子上的物体上,影子的长度会变短,而随着手电筒的降低,影子的长度会增加。那么Android的MaterialDesign中的光源在哪里呢?在顶部?还是棱角分明?经过一番研究,我发现了这个现象。Android中有两种光源,最上面的一种是关键光源,另一种是环境光源,我们看到的影子其实就是这两种光源的组合。让我们看看显示效果如何。在Android中,我们有很多小部件。按钮、CardView、对话框、抽屉等都是视图。如果有光源,我们就会有阴影。那么我们在Android中如何决定Z值呢?材料设计如何规定这一点?有一个示意图可以反映这种情况。静止或按下正如我之前提到的,在AndroidFramework中,一些动画是为小部件实现的。如果您在布局中放置一个浮动操作按钮,默认情况下它的高度为6dp。但是你会注意到,当你按下按钮时,FAB的Elevation会增加到12dp。让我告诉你在这个过程中发生了什么。事实上,FAB有一个6dp的Elevation。当您按下按钮时,translationZ值开始增加。ViewPropertyAnimator通过将translationZ值从0dp更改为6dp来为视图设置动画。如果松开按钮,ViewPropertyAnimator将进行动画处理,将translationZ从6dp更改为0dp。您可以为您的视图创建自定义状态列表动画并将它们添加到您的视图之上。我们来看看这个过程的流程图。阴影的秘密:OutlineOutline是属于android.graphic的一个类。看它的文档是怎么说的,为图形的边框区域定义一个简单的形状。可以为View或由Drawable计算,以驱动View投射的阴影形状,或裁剪View的内容。每个View都有一个默认的轮廓来显示它的阴影。如果我们创建一个自定义形状的可绘制对象,其轮廓将根据其形状在内部计算。所以,如果我们画一个圆,那么轮廓就是圆的。如果我们画一个矩形,那么轮廓就是一个矩形。总而言之,有一个Outlin可以让你以无形的方式看到这个效果。但是,如果我想创建自定义视图并动态更改其边界怎么办?Android是否为我的自定义视图提供大纲?Android当然为我们提供了自定义Outline的方式,那就是:ViewOutlineProvider。什么是ViewOutlineProvider?在我最近开源的ScalingLayout库中,我并没有在自定义视图上实现阴影效果。我觉得很漂亮,没有阴影。但请记住材料设计、3D、深度、Z值的基础知识。在这个动画中,我们可能无法确定哪些地方可以点击,缩放布局中也没有阴影。接下来我们为自定义视图提供动态大纲。publicclassScalingLayoutOutlineProvider扩展ViewOutlineProvider{@OverridepublicvoidgetOutline(Viewview,Outlineoutline){outline.setRoundRect(0,0,width,height,radius);}}publicclassScalingLayoutextendsFrameLayout{//...viewOutline=newScalingLayoutOutlineProvider(wlineh,currentProvider);setRadius);//..}这样,我们就为自定义View添加了高度支持。更多关于ViewOutlineProvider的用法,简化了一些基础知识,你可以在ScalingLayout中找到详细信息。https://github.com/iammert/ScalingLayout【本文为专栏作者“张扬”原创稿件,转载请微信联系作者♂获得授权】点此查看作者更多好文
