写一个轻量的用户引导工具:Android自定义View之GuideView
程序员文章站
2022-07-05 09:06:59
...
自定义自己的轻量级GuideView,满足app的正常引导需求,半透明灰色蒙板,控件高亮展示,添加引导说明。
将主要代码贴出做简单解释。
首先自定义蒙板View
onDraw()方法中关键代码如下
setLayerType(View.LAYER_TYPE_SOFTWARE, null); //需要关闭硬件加速,否则混合模式显示无效
Paint paint = new Paint(); //新建画笔
paint.setAntiAlias(true); //抗锯齿
setBackgroundColor(Color.TRANSPARENT); //设置画布背景透明
paint.setColor(0xa0000000); //设置画笔颜色半透明
canvas.drawRect(0,0,width,height,paint); //半透明画满整个画布,with、height为自定义View宽高
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); //设置图像混合模式为clear
paint.drawRect(left,top,right,bottom,paint); //绘制镂空图形
PorterDuff.Mode.CLEAR:上层绘制不会提交到画布,并把与下层交集部分也清除,类似镂空,设置此混合模式之后画笔所画图形部分就为镂空部分
其他混合模式如下:
PorterDuff.Mode.CLEAR |
上层绘制不会提交到画布,并把与下层交集部分也清除 |
PorterDuff.Mode.SRC |
显示上层绘制,此时下层绘制也会显示 |
PorterDuff.Mode.DST |
显示下层绘制,而上层不会绘制 |
PorterDuff.Mode.SRC_OVER |
正常显示,上层叠盖在下层之上 |
PorterDuff.Mode.DST_OVER |
上下层都显示,下层在上 |
PorterDuff.Mode.SRC_IN |
将交集显示在下层绘制的区域 |
PorterDuff.Mode.DST_IN |
显示下层绘制 |
PorterDuff.Mode.SRC_OUT |
取非交集区域 |
PorterDuff.Mode.DST_OUT |
取下层非交集区域 |
PorterDuff.Mode.SRC_ATOP |
取上层的交集区域和下层的非交集区域 |
PorterDuff.Mode.DST_ATOP |
下层在上层之上 |
PorterDuff.Mode.XOR |
去除两层的交集区域 |
PorterDuff.Mode.DARKEN |
取两层全部区域,交集区域变暗 |
PorterDuff.Mode.LIGHTEN |
取两层全部区域,交集区域变亮 |
PorterDuff.Mode.MULTIPLY |
取下层全部区域,交集区域色彩叠加,正片叠底 |
PorterDuff.Mode.SCREEN |
取两层全部区域,交集区域变透明 |
PorterDuff.Mode.ADD |
饱和度叠加 |
PorterDuff.Mode.OVERLAY |
对黑白无效,显示两层颜色中和后的中间色 |
自定义蒙板完成之后就需要在页面中显示出来了,通过context.getWindow().getDecorView(),来获取根视图,通过根视图的addView方法将蒙版添加进视图层,相应的引导说明布局也以相同的方式添加,用LayoutInflater.from(context).inflate(R.layout.explain,null)得到布局,再以相同的方式addView添加进视图层。
基本原理很简单,下面是GuideView的使用。
在主工程build.gradle中添加maven { url 'https://jitpack.io'},如下
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io'}
}
}
在需要使用GuideView的工程中引入implementation "com.github.yangdonghaohpu:GuideView:0.3" 如下
dependencies {
implementation "com.github.yangdonghaohpu:GuideView:0.3"
}
同步之后即可在需要用到的页面调用,方法如下:
//简单使用
GuideView.with(this).setOnView(tv).show();
//定制使用
GuideView.with(this)
.setShadowSize(10) //高量控件边缘阴影大小,不设置默认无阴影
.setShapeType(GuideView.OVAL) //高亮控件显示的图形,RECTANGLE矩形、CIRCLE圆形、OVAL椭圆,不设置默认矩形
.setOnView(tv,tv1,tv2) //需要高亮展示的控件、可传入多个控件、按顺序依次展示,不设置默认只展示灰色蒙板
.setDismissCallback(new ViewBuilder.DismissCallback() { //高亮展示完成的回调
@Override
public void dismiss() {
Log.e("消失","回调");
}
})
.setExplainViews(GuideView.buildExplainView(R.layout.layout_notice,50,50,0,0) //创建布局文件参数说明(布局layoutID,布局相对控件左上角的marginLeft值,布局相对控件左上角的marginTop值,布局相对屏幕的marginRight值,布局相对屏幕的marginBottom值)
,GuideView.buildExplainView(R.layout.layout_notice,50,-100,0,0)
) //需要对高亮展示的控件进行说明的布局,与setOnView()中传如的控件按顺序依次对应,不传或传null,则不展示说明布局
.show();
显示效果在这里不做展示了,有兴趣的同学可以项目里引用看下效果。
通常蒙板引导只需要新安装用户或者更新版本的用户在进入应用之后展示引导一次即可,再次打开应用则不再展示引导,这里工具中没有集成这个是否需要展示的判断,需要用到的同学根据具体场景自行判断吧,这个后续可以改进。