前语
在 Android
的界面制作中,控件的暗影是我们经常会处理的一种界面元素,尤其会呈现在按钮 Button
这种需求吸引用户关注点的控件上。Android
原生供给了控件的 Z
轴特点即 elevetion
供暗影作用,可是这个作用嘛,但凡是有一点想法的 UI
都不会满足的,比方我司的,就坚决不接受。
常见的问题比方不支撑特定的暗影形状或巨细,或不允许完全自定义暗影的色彩或透明度,切图是一种办法,可是自定义 View 制作的作用会更好,究竟切图会实实在在的形成 apk
包体积的增大,而且屏幕适配也会是一个潜藏的问题危险。
结合我的经历,简单封装了一下,共享我目前运用的 ShadowView
运用
圆角矩形暗影
-
一般暗影
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <com.randalldev.shadowview.ShadowView android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="@id/btn_target" app:layout_constraintEnd_toEndOf="@id/btn_target" app:layout_constraintStart_toStartOf="@id/btn_target" app:layout_constraintTop_toTopOf="@id/btn_target" app:shadowBottomHeight="16dp" app:shadowCardColor="#FF7043" app:shadowColor="#FFEE58" app:shadowLeftHeight="16dp" app:shadowRadius="16dp" app:shadowRightHeight="16dp" app:shadowRound="8dp" app:shadowTopHeight="16dp" /> <Button android:id="@+id/btn_target" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@android:color/transparent" android:paddingStart="40dp" android:paddingEnd="40dp" android:paddingTop="20dp" android:paddingBottom="20dp" android:text="target button" android:textColor="@color/purple_700" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
抛开配色不谈,这个作用还能够吧
-
一般暗影 + 偏移
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout app:shadowLeftHeight="16dp" app:shadowOffsetX="8dp" app:shadowOffsetY="4dp" app:shadowRadius="16dp" </androidx.constraintlayout.widget.ConstraintLayout>
圆形暗影
圆形暗影也能够认为是一种特殊的圆角矩形暗影,能够持续沿用圆角矩形的办法,或许增加 shadowShape
特点。
假如要运用圆角矩形的办法,需求事前确认方针控件的尺度,这可能会遇到屏幕适配问题,所以我这儿就直接演示运用 shadowShape
特点的办法
-
一般暗影
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout app:shadowCardColor="#FF7043" app:shadowColor="#FFEE58" app:shadowRadius="16dp" app:shadowShape="1" /> <Button android:id="@+id/btn_target" android:layout_width="wrap_content" android:layout_height="0dp" android:background="@android:color/transparent" android:padding="20dp" android:text="target button" android:textColor="@color/purple_700" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="1:1" </androidx.constraintlayout.widget.ConstraintLayout>
很简单吧,相比圆角矩形的配置,多了一个
shadowShape
可是少了很多尺度的设置,只需求设置一个shadowRaduis
即可。需求留意的是,我这儿运用了
ConstrainLayout
的ratio
特点设置为1:1
来完成一个正方形的方针控件,由于在制作圆形时,是以控件的中心作为圆心来制作的,假如不是正方形就可能呈现问题了。 -
一般暗影 + 偏移
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout app:shadowCardColor="#FF7043" app:shadowColor="#FFEE58" app:shadowRadius="16dp" app:shadowOffsetX="4dp" app:shadowOffsetY="4dp" app:shadowShape="1" /> </androidx.constraintlayout.widget.ConstraintLayout>
这个运用起来仍是比较便利的吧,只需求方针控件设置
padding
留出足够的空间制作暗影作用即可。而且不需求再写
drawable
文件设置控件的背景了。当然也不是没有缺陷,目前仍是只能兼容圆角矩形和圆形。异形的暂时没用到,可能也不会去做支撑。
完成
什么是暗影
首先,暗影是什么?
在真实世界中,暗影是物体遮挡住光源的光路呈现的现象;在 Android View
系统中则是 Z
轴高度,Z
轴高度越高,暗影范围越大,色彩越深。
可是只是通过 elevetion
特点设置 Z
轴高度完成的暗影视效上往往只能说满足有无的问题,究竟国内谁按照 MD
风格去规划界面啊。
那么,暗影是什么?
当我们自定义 View 去制作暗影的时候,其实也能够是一圈从边际向四周放射式扩散的渐变色层,从而形成一种视觉的暗影作用。
那偏移又是什么?
偏移其实便是表达光源的位置,偏移为 0,即光源在正中心光线直射,暗影作用是从边际均匀的向四周逐渐变淡。
X
偏移为正,则光源在中心偏右,Y
偏移为正,则光源在中心偏下。 若为负数则相反。视觉上则会呈现某一或两轴方向上的暗影区域偏少。
上代码
初始化
这段很简单,便是读取 attrs
特点,设置硬件加速
init {
initView(context, attrs)
//设置软件烘托类型,跟制作暗影相关,后边会说
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
}
制作暗影
这儿创立了一个画笔 Paint
的实例,画笔的色彩是方针控件的背景色;制作形式设置的是 FILL
表明填充形式,还有 STROKE
描边形式,FILL_AND_STROKE
描边加填充形式;AntiAlias
设置为 true
标识敞开抗锯齿。
这儿便是运用 Paint
的 setShadowLayer()
办法创立暗影作用,其中:
-
radius
:暗影半径,值越大暗影越含糊,值为0时暗影消失。 -
dx
:暗影在水平方向的偏移量,正值表明向右偏移,负值表明向左偏移。 -
dy
:暗影在笔直方向的偏移量,正值表明向下偏移,负值表明向上偏移。 -
shadowColor
:暗影色彩。
Canvas
能够理解为画布,根据 shadowShape
特点在画布上对应的制作圆角矩形和圆形两种不同形状。
-
drawRoundRect()
用于在Canvas
上制作一个圆角矩形。该办法需求传递四个参数,分别是矩形左上角的X
坐标,矩形左上角的Y
坐标,矩形右下角的X
坐标和矩形右下角的Y
坐标。此外还需求供给两个额定参数,分别是圆角的X
半径和Y
半径。 -
canvas.drawCircle()
用于在Canvas
上制作一个圆形。该办法需求传递三个参数,分别是圆心的X
坐标,圆心的Y
坐标以及圆的半径。
创立一个 RectF
,也便是一个矩形目标,表明一个浮点数精度的矩形。在制作操作,比方指定制作区域、裁剪画布等经常会用到。其结构函数包括4个浮点型成员变量:left、top、right、bottom,分别表明矩形左鸿沟、上鸿沟、右鸿沟和下鸿沟的坐标值。
override fun dispatchDraw(canvas: Canvas) {
// 配置画笔
val shadowPaint = Paint()
shadowPaint.color = shadowCardColor
shadowPaint.style = Paint.Style.FILL
shadowPaint.isAntiAlias = true
val left = shadowLeftHeight.toFloat()
val top = shadowTopHeight.toFloat()
val right = (width - shadowRightHeight).toFloat()
val bottom = (height - shadowBottomHeight).toFloat()
// 配置暗影的范围,偏移,色彩
shadowPaint.setShadowLayer(shadowRadius.toFloat(), shadowOffsetX.toFloat(), shadowOffsetY.toFloat(), shadowColor)
if (shadowShape == 0) {
// 假如制作圆角矩形的暗影,用 drawRoundRect
val rectF = RectF(left, top, right, bottom)
canvas.drawRoundRect(rectF, shadowRound.toFloat(), shadowRound.toFloat(), shadowPaint)
} else {
// 假如制作圆形的暗影,用 drawCircle
val radius = measuredHeight.toFloat() / 2 - shadowRadius
canvas.drawCircle(measuredHeight.toFloat() / 2, measuredHeight.toFloat() / 2, radius, shadowPaint)
}
shadowPaint.utilReset()
canvas.save()
}
总结
在 Android
界面制作中,暗影是常见的 UI
元素之一,而 Android
原生供给的 elevation
特点虽然能够完成暗影作用,但往往不能满足 UI
规划的要求。因此,自定义 View
制作暗影的办法更为灵敏和实用。本文介绍了 ShadowView
,它能够便利地制作圆角矩形和圆形的暗影,且支撑色彩、透明度和暗影形状的自定义。此外,本文还供给了运用 ShadowView
制作暗影的示例代码,可供读者参阅和运用。通过运用 ShadowView
,能够愈加便利地完成杂乱、美观的暗影作用,提高 Android
使用的用户体会。
参阅文章
Android进阶:快速完成自定义暗影作用
ShadowView