热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android自定义View引导蒙版

引导蒙版引导蒙版分为三部分1、高亮显示的目标布局2、围绕着目标布局的围栏布局3、用于提示的蒙版布局DEMO地址:https:github.comchaozhouzha
引导蒙版

引导蒙版分为三部分 

1、高亮显示的目标布局 

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

3、用于提示的蒙版布局

DEMO地址:https://github.com/chaozhouzhang/CustomProgressView

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();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的使用与源码解析可以看本公众号的文章:

LayoutInfalter的使用与源码解析

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

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

添加:

mContentParent.post(new Runnable() {@Overridepublic 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() {@Overridepublic void onClick(View v) {dismiss();if (mOnDismissListener != null) {mOnDismissListener.onDismiss();}}});
}

移除:

public void dismiss() {mContentParent.post(new Runnable() {@Overridepublic 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() {@Overridepublic void onDismiss() {//关闭后显示下一个蒙版int nextPosition = mPosition + 1;if (mGuideMasks.size() > nextPosition) {GuideMask next = mGuideMasks.get(nextPosition);mPosition++;next.show();}}});
}

推荐阅读
你亲手写的代码,正在出卖你

深夜,聊聊架构设计

深夜,分享一个Git小技巧

编程·思维·职场
欢迎扫码关注


推荐阅读
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • 深入解析 Lifecycle 的实现原理
    本文将详细介绍 Android Jetpack 中 Lifecycle 组件的实现原理,帮助开发者更好地理解和使用 Lifecycle,避免常见的内存泄漏问题。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • 一个建表一个执行crud操作建表代码importandroid.content.Context;importandroid.database.sqlite.SQLiteDat ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 解决Only fullscreen opaque activities can request orientation错误的方法
    本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ... [详细]
  • 原文网址:https:www.cnblogs.comysoceanp7476379.html目录1、AOP什么?2、需求3、解决办法1:使用静态代理4 ... [详细]
  • 本文详细解析了 Yii2 框架中视图和布局的各种函数,并综述了它们在实际开发中的应用场景。通过深入探讨每个函数的功能和用法,为开发者提供了全面的参考,帮助他们在项目中更高效地利用这些工具。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 【问题】在Android开发中,当为EditText添加TextWatcher并实现onTextChanged方法时,会遇到一个问题:即使只对EditText进行一次修改(例如使用删除键删除一个字符),该方法也会被频繁触发。这不仅影响性能,还可能导致逻辑错误。本文将探讨这一问题的原因,并提供有效的解决方案,包括使用Handler或计时器来限制方法的调用频率,以及通过自定义TextWatcher来优化事件处理,从而提高应用的稳定性和用户体验。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 体积小巧的vsftpd与pureftpd Docker镜像在Unraid系统中的详细配置指南:支持TLS加密及IPv6协议
    本文详细介绍了如何在Unraid系统中配置体积小巧的vsftpd和Pure-FTPd Docker镜像,以支持TLS加密和IPv6协议。通过这些配置,用户可以实现安全、高效的文件传输服务,适用于各种网络环境。配置过程包括镜像的选择、环境变量的设置以及必要的安全措施,确保了系统的稳定性和数据的安全性。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有