引导蒙版

引导蒙版分为三部分

1、高亮显示的目标布局

2、围绕着目标布局的围栏布局

3、用于提示的蒙版布局

GuideMask guideMask = new GuideMask.Builder(this)

//蒙版所在activity

.setMaskActivity(this)

//目标布局

.setTargetView(mIvTest)

//蒙版背景颜色包括透明度

.setBgColor(Color.parseColor("#40000000"))

//蒙版布局

.setMaskLayout(R.layout.layout_mask)

//关闭蒙版的按钮

.setMaskCloseId(R.id.btn_close)

//围栏与目标布局的距离

.setFencePadding(0,0,0,0)

//围栏布局四角的角度

.setFenceRadius(100)

.build();

GuideMaskSet guideMaskSet = new GuideMaskSet();

//添加蒙版

guideMaskSet.addGuide(guideMask);

//显示所有蒙版

guideMaskSet.show();

复制代码

1、自定义FrameLayout

在ViewGroup中,初始化时设置了WILL_NOT_DRAW,设置WILL_NOT_DRAW之后,onDraw()不会被调用,目的是略过绘制的过程,优化了性能。所以,在写自定义ViewGroup布局时,如果需要调用onDraw()进行绘制,则需要在初始化时候,调用setWillNotDraw(false)。

setWillNotDraw(false);

复制代码

2、使用LayoutInflater解析蒙版布局,并添加到当前自定义布局中

配置root为当前自定义布局,配置attachToRoot为true,也就是解析蒙版布局结束后,直接添加到当前自定义布局中。

LayoutInfalter的使用与源码解析可以看本公众号的文章:

mMaskLayoutView = LayoutInflater.from(mMaskActivity).inflate(mMaskLayout, this, true);

复制代码

3、将自定义布局添加到activity的content布局中

添加:

mContentParent.post(new Runnable() {

@Override

public void run() {

//显示蒙版,也就是将当前蒙版加到mContentParent的FrameLayout布局上

mContentParent.addView(GuideMask.this, new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

}

});

复制代码

找到关闭蒙版的ID控件,点击后将自定义布局从activity的content布局中移除:

if (mCloseId != 0) {

//在蒙版布局中找到点击关闭蒙版的控件

mMaskLayoutView.findViewById(mCloseId).setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

dismiss();

if (mOnDismissListener != null) {

mOnDismissListener.onDismiss();

}

}

});

}

复制代码

移除:

public void dismiss() {

mContentParent.post(new Runnable() {

@Override

public void run() {

//关闭蒙版,也就是将当前蒙版从mContentParent的FrameLayout布局上移除

mContentParent.removeView(GuideMask.this);

}

});

}

复制代码

4、绘制围栏布局,以突出目标布局

4.1、设置围栏的画笔

图像过渡模式,设置为清除模式,用于显示目标布局:

//首先xfermode绘图需要两部分,DST,SRC 两种。可以理解为DST 在下边,SRC在上面。也就是说DST先绘制,SRC 后绘制。

//PorterDuff.Mode.CLEAR:清除模式,[0, 0],即图像中所有像素点的alpha和颜色值均为0。

PorterDuff.Mode mode = PorterDuff.Mode.CLEAR;

mFenceClearMode = new PorterDuffXfermode(mode);

//这个方法用于设置图像的过渡模式,所谓过渡是指图像的饱和度、颜色值等参数的计算结果的图像表现。

//设置围栏区域为清除模式,以达到显示目标布局的目的

mFencePaint.setXfermode(mFenceClearMode);

复制代码

设置画笔遮罩滤镜,用于凸出目标布局:

//设置画笔遮罩滤镜,传入BlurMaskFilter或EmbossMaskFilter,前者为模糊遮罩滤镜而后者为浮雕遮罩滤镜。

//如果应用启用了硬件加速,将看不到任何阴影效果。

mFencePaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.INNER));

//关闭当前View的硬件加速。

setLayerType(LAYER_TYPE_SOFTWARE, null);

复制代码

4.2、onDraw绘制围栏

获取目标布局和content布局的位置坐标:

/**

* 获取当前蒙版所目标的布局的坐标位置。

*/

mTargetView.getGlobalVisibleRect(mTargetRect);

复制代码

/**

* getGlobalVisibleRect()是View可见区域相对与屏幕来说的坐标位置。

* getLocalVisibleRect()是View可见区域想对于自己坐标的位置。

* 获取当前蒙版所在activity根布局的坐标位置。

*/

mContentParent.getGlobalVisibleRect(mContentRect);

复制代码

计算围栏布局的位置坐标:

/**

* 需要绘制的坐标位置

*/

int topMargin = mContentRect.top;

int left = mTargetRect.left - mPaddingLeft;

mFenceRectF.left = left;

int right = mTargetRect.right + mPaddingRight;

mFenceRectF.right = right;

int top = mTargetRect.top - mPaddingTop - topMargin;

mFenceRectF.top = top;

int bottom = mTargetRect.bottom + mPaddingBottom - topMargin;

mFenceRectF.bottom = bottom;

/**

* rx:x方向上的圆角半径。

* ry:y方向上的圆角半径。

*/

canvas.drawRoundRect(mFenceRectF, mRadius, mRadius, mFencePaint);

复制代码

5、建造者模式构建蒙版

GuideMask guideMask = new GuideMask.Builder(this)

//蒙版所在activity

.setMaskActivity(this)

//目标布局

.setTargetView(mIvTest)

//蒙版背景颜色包括透明度

.setBgColor(Color.parseColor("#40000000"))

//蒙版布局

.setMaskLayout(R.layout.layout_mask)

//关闭蒙版的按钮

.setMaskCloseId(R.id.btn_close)

//围栏与目标布局的距离

.setFencePadding(5,5,5,5)

//围栏布局四角的角度

.setFenceRadius(100)

.build();

复制代码

6、整合蒙版集合,关闭蒙版后显示下一个蒙版

/**

* 添加蒙版

* @param guideMask

*/

public void addGuide(GuideMask guideMask) {

mGuideMasks.add(guideMask);

guideMask.setOnDismissListener(new GuideMask.OnDismissListener() {

@Override

public void onDismiss() {//关闭后显示下一个蒙版

int nextPosition = mPosition + 1;

if (mGuideMasks.size() > nextPosition) {

GuideMask next = mGuideMasks.get(nextPosition);

mPosition++;

next.show();

}

}

});

}

复制代码

欢迎关注公众号,Android技术堆栈:

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐