一、关于硬件加速
官方文档
1、简述
GPU:图形处理器,用来加速图形的渲染速度
Andorid中,在API 11(3.0)之后,加入了对GPU加速的支持,在API 14(4.0)之后,硬件加速是默认开启的.
2、问题
因为在API >= 14时硬件加速默认开启,如果你的app全部是原生的组件,是不会有任何问题的,但是我们的应用中一般都会有自定义组件,而自定义组件时有些方法是不支持硬件加速或者支持的版本很高,所以这就会出现问题.
3、自定义组件时一些方法支持硬件加速的版本( 摘自官方文档 )
API代表这些方法在>=这些版本才支持硬件加速,红叉代表不支持
4、硬件加速开启与关闭
硬件加速可以在4个级别来控制
(1)Application级别
......
支持开启、关闭
(2)Activity级别
支持开启、关闭
(3)Window级别
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
只支持开启
(4)View级别
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
或者在布局文件中通过layerType属性关闭硬件加速
android:layerType="software"
只支持关闭
二、阴影
1、介绍
Paint中有一个专门用来实现阴影效果的方法:
public void setShadowLayer(float radius, float dx, float dy, int shadowColor)
radius:阴影半径,设为0就是取消阴影
dx:阴影x轴偏移距离,大于0向右偏移,小于0向左偏移
dy:阴影y轴偏移距离,大于0向下偏移,小于0向上偏移
color:阴影的颜色(对图片阴影无效)
从上面的硬件加速图片中可以找到这个方法:该方法对绘制文本阴影支持硬件加速,其它的都不支持硬件加速,所以,我们在自定义控件中使用到这个方法时,一般都要关闭硬件加速.
2、使用
private void gogogo(Canvas canvas) {
this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
mPaint.setColor(Color.BLUE);
mPaint.setTextSize(66);
mPaint.setShadowLayer(10, 5, 5, Color.GRAY);//阴影
canvas.drawText("随风飘扬的Smile", 100, 100, mPaint);
canvas.drawCircle(200, 200, 50, mPaint);
}
3、移除阴影
一旦我们定义了阴影层,后面绘制的都会带上阴影,如果想取消阴影,可以使用Paint的下面这个方法:
public void clearShadowLayer() {
setShadowLayer(0, 0, 0, 0);
}
4、TextView及其子类阴影
对于原生的TextView及其子类,都支持通过XML设置阴影
这几个属性对照上面setShadowLayer的参数一看就明白了.
当然,通过代码设置也是可以的:
public void setShadowLayer(float radius, float dx, float dy, int color)
三、Alpha滤镜
1、setMaskFilter
public MaskFilter setMaskFilter(MaskFilter maskfilter)
在前一篇Paint之颜色过滤中介绍了画笔Paint如何设置颜色滤镜(setColorFilter),这里setMaskFilter介绍的也是滤镜.
和setColorFilter方法介绍的差不多,setMaskFilter方法需要一个MaskFilter 对象,而MaskFilter类中基本啥都没有,所以这里需要的其实是它的2个子类:
注意:setMaskFilter这个方法也是不支持硬件加速的
2、BlurMaskFilter 模糊滤镜
public BlurMaskFilter(float radius, Blur style)
radius:模糊半径
style:模糊样式,可选值:
BlurMaskFilter.Blur.NORMAL 内外模糊
BlurMaskFilter.Blur.SOLID 图像边界外产生与Paint颜色一致的阴影效果
BlurMaskFilter.Blur.OUTER 外部模糊,同时将原图像透明
BlurMaskFilter.Blur.INNER 内部模糊
来看一下它们的效果:
private void gogogo(Canvas canvas) {
this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
mPaint.setColor(Color.BLUE);
mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.NORMAL));
// mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.SOLID));
// mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.OUTER));
// mPaint.setMaskFilter(new BlurMaskFilter(66, BlurMaskFilter.Blur.INNER));
canvas.drawCircle(200, 200, 100, mPaint);
}
3、EmbossMaskFilter 浮雕滤镜
EmbossMaskFilter 可以让绘制的图形体现出浮雕的效果.
浮雕效果:模拟光照效果,靠近光的一面显得亮一点,远离光的一面显得暗一点,这样就通过颜色的亮暗营造出浮雕的3D立体效果.
public EmbossMaskFilter(float[] direction, float ambient, float specular, float blurRadius)
direction:一个float类型的数组,表示光线的方向,包含三个值---[x, y, z],是一个空间立体坐标系在三个方向的值,最终形成光照方向
ambient:环境光亮度,取值是0到1,值越接近于0,环境光越暗,值越接近于1,环境光越亮
specular:镜面反射系数
blurRadius:浮雕效果中“凸”起的大小
下面来看一看具体效果:
private void gogogo(Canvas canvas) {
this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
mPaint.setColor(Color.BLUE);
mPaint.setTextSize(66);
EmbossMaskFilter filter = new EmbossMaskFilter(new float[]{1, 1, 3}, 0.4f, 8, 3);//浮雕滤镜
mPaint.setMaskFilter(filter);
canvas.drawText("随风飘扬的笑", 100, 100, mPaint);
}
这个滤镜在实际开发中使用率很低,因为最终效果不是很好控制.