NewbieGuide

项目地址:huburt-Hu/NewbieGuide 

简介:Android 快速实现新手引导层的库,通过简洁链式调用,一行代码实现引导层的显示

更多:作者   提 Bug

标签:

Android 快速实现新手引导层的库

这是一款可以通过简洁链式调用,一行代码实现引导层的显示,自动判断首次显示,当然也可以通过参数配置来满足不同的显示逻辑和需求。 通过自定义 layout.xml 实现文本及 image 的添加,非常方便位置的调整,避免代码调整各种不好控制的情况:实验 5,6 次才最终确定文字等的位置。

更新日志

更新日志

效果

改变高亮 view 的尺寸,并不用调整显示引导层的代码


引导层的 xml 可以完全自定义,像怎样显示就怎样显示

此库依赖

compileOnly 'com.android.support:appcompat-v7:25.3.1'

导入

项目的 build.gradle 添加

allprojects {repositories {...maven { url 'https://jitpack.io' }}}

module 的 build.gradle 添加

 dependencies {compile 'com.github.huburt-Hu:NewbieGuide:v2.4.0'}

确保你的项目中已经依赖了 appcompat-v7

使用

简单使用

NewbieGuide.with(activity).setLabel("guide1").addGuidePage(GuidePage.newInstance().addHighLight(btnSimple).setLayoutRes(R.layout.view_guide_simple)).show();

通过链式调用,一行代码即可实现引导层的显示,来看下效果:

其中:

  • with方法可以传入 Activity 或者 Fragment,获取引导页的依附者。Fragment 中使用建议传入 fragment,内部会添加监听,当依附的 Fragment 销毁时,引导层自动消失。
  • setLabel方法用于设置引导页的标签,区别不同的引导页,该方法必须调用设置,否则会抛出异常。内部使用该 label 控制引导页的显示次数。
  • addGuidePage方法添加一页引导页,这里的引导层可以有多个引导页,但至少需要一页。
  • GuidePage即为引导页对象,表示一页引导页,可以通过.newInstance()创建对象。并通过addHighLight添加一个或多个需要高亮的 view,该方法有多个重载,可以设置高亮的形状,以及 padding 等(默认是矩形)。setLayoutRes方法用于引导页说明布局,就是上图的说明文字的布局。
  • show方法直接显示引导层,如果不想马上显示可以使用build方法返回一个 Controller 对象,完成构建。需要显示得时候再次调用 Controller 对象的 show 方法进行显示。

添加高亮

高亮 view

addHighLight 方法有多个重写,完整参数如下:

    /*** 添加需要高亮的 view** @param view          需要高亮的 view* @param shape         高亮形状{@link com.app.hubert.guide.model.HighLight.Shape}* @param round         圆角尺寸,单位 dp,仅{@link com.app.hubert.guide.model.HighLight.Shape#ROUND_RECTANGLE}有效* @param padding       高亮相对 view 的 padding,单位 px* @param relativeGuide 相对于高亮的引导布局*/public GuidePage addHighLight(View view, HighLight.Shape shape, int round, int padding, @Nullable RelativeGuide relativeGuide)

高亮区域(v2.3.0 新增)

有些情况可能不太容易获得高亮 view 的引用,那么此时可以用添加高亮区域的方式来代替, 计算出需要高亮的 view 在 anchor 中位置,将获得的 rectF 传入 addHighLight 方法

    /*** 添加高亮区域** @param rectF         高亮区域,相对于 anchor view(默认是 android.R.id.content)* @param shape         高亮形状{@link com.app.hubert.guide.model.HighLight.Shape}* @param round         圆角尺寸,单位 dp,仅{@link com.app.hubert.guide.model.HighLight.Shape#ROUND_RECTANGLE}有效* @param relativeGuide 相对于高亮的引导布局*/public GuidePage addHighLight(RectF rectF, HighLight.Shape shape, int round, @Nullable RelativeGuide relativeGuide)

高亮区域点击事件(v2.4.0 新增)

之前也是 issues 中提到需要这个功能,希望能够开放此 api,因此在 2.4 版本中增加了。 由于目前高亮 view 的相关参数过多,因此将一些新增的配置都放入了 HighlightOptions 中,HighlightOptions 可以通过内部 Builder 对象构建:

HighlightOptions options = new HighlightOptions.Builder().setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(FirstActivity.this, "highlight click", Toast.LENGTH_SHORT).show();}}).build();
GuidePage page = GuidePage.newInstance().addHighLightWithOptions(btnRelative, options);
NewbieGuide.with(FirstActivity.this).setLabel("relative").alwaysShow(true)//总是显示,调试时可以打开.addGuidePage(page).show();

自定义高亮区域绘制内容(v2.4.0 新增)

该功能主要是为了满足issue51提出的需求。

首先构建一个 HighlightOptions,并设置 OnHighlightDrewListener:

HighlightOptions options = new HighlightOptions.Builder().setOnHighlightDrewListener(new OnHighlightDrewListener() {@Overridepublic void onHighlightDrew(Canvas canvas, RectF rectF) {Paint paint = new Paint();paint.setColor(Color.WHITE);paint.setStyle(Paint.Style.STROKE);paint.setStrokeWidth(10);paint.setPathEffect(new DashPathEffect(new float[]{20, 20}, 0));canvas.drawCircle(rectF.centerX(), rectF.centerY(), rectF.width() / 2 + 10, paint);}}).build();

onHighlightDrew 方法会在引导层绘制高亮之后马上回调,可通过 canvas,以及给定的高亮区域 rectF,绘制想要任何视图,例如上述示例中完成的 issue 提出的虚线。

然后与高亮区域点击事件类似,传入 highlight 以及 option 到 addHighLightWithOptions 方法中:

GuidePage page = GuidePage.newInstance().addHighLightWithOptions(btnRelative, options);

显示次数控制

通常情况下引导页只在用户首次打开 app 的时候显示,第二次进入时不显示,因此默认只显示一次。当然你也可以通过.setShowCounts(3)自定义显示的次数,调试的时候可以使用.alwaysShow(true)设置每次都显示。

NewbieGuide.with(activity).setLabel("guide1")//.setShowCounts(3)//控制次数.alwaysShow(true)//总是显示,调试时可以打开.addGuidePage(GuidePage.newInstance().addHighLight(btnSimple).setLayoutRes(R.layout.view_guide_simple)).show();

就算设置了.alwaysShow(true),内部还是会记录显示得次数,之后改会setShowCounts(3)可能实际记录的次数早已超过限制,因此不会再次显示。使用 Controller 对象的resetLabel方法重置次数。(或者清除应用缓存也能重置次数)

引导布局

着重说明一下 setLayoutRes 方法,通常其他的类似的库都是通过代码参数来控制说明内容展示在高亮 view 相对的位置,如下方。经常需要多次运行才能找到满意的位置的参数。大多说明内容只能出现在高亮的上下左右,需要库的支持,自定义的程度不是很高。

我所采用的方式是将说明内容通过 xml 的方式,自定义摆放位置。使得说明内容高度自定义,不管你是简单的图片,还是对话框类型的都可以。

GuidePage.newInstance().addHighLight(btnDialog).setEverywhereCancelable(false)//是否点击任意位置消失引导页,默认 true.setLayoutRes(R.layout.view_guide_dialog, R.id.btn_ok).setOnLayoutInflatedListener(new OnLayoutInflatedListener() {@Overridepublic void onLayoutInflated(View view, Controller controller) {TextView tv = view.findViewById(R.id.tv_text);}})

该方法还有一个可变参数setLayoutRes(@LayoutRes int resId, int... id),传入 id 数组表示在布局中点击让引导页消失或者进入下一页的 View(例如,Button ok 的 id)。 setOnLayoutInflatedListener设置布局填充完成的监听,当传入的 xml(R.layout.view_guide_dialog)填充完成时会回答调用该监听,用于初始化自定布局的元素。

相对高亮位置的引导布局(v2.3.0 新增)

鉴于好多人提出上面的方法对于箭头指向的引导控制起来比较麻烦,在不用的手机屏幕尺寸上会有位置差异。 因此 v2.3 版本新增在高亮相对位置添加引导布局的方法。扩展 addHighLight 方法的重载,新增参数 RelativeGuide:

.addGuidePage(GuidePage.newInstance().addHighLight(btnRelative, new RelativeGuide(R.layout.view_relative_guide,Gravity.RIGHT, 100))
)

RelativeGuide 构造需要 2 个必传参数:

  • 布局 layout 的 res id;
  • gravity 目前仅支持 Gravity.LEFT Gravity.TOP Gravity.RIGHT Gravity.BOTTOM

还有一个可选参数 padding,表示与高亮 view 的 padding

引导层本质是一个 FrameLayout,RelativeGuide 与 setLayoutRes 都会成为 FrameLayout 的子 view,两者可以共存, setLayoutRes 在下层,多个 RelativeGuide 按照添加顺序依次添加。

各个方向的对齐方式如下图所示:

如 Gravity.LEFT 的 top 与高亮 view 的 top 对齐,如果想改变,可以通过在传入布局的根布局添加 marginTop。 或者还可以继承 RelativeGuide 并复写 offsetMargin 方法修改位置,具体细节可查看 RelativeGuide 类。

引导页控制(v2.2.1 版本新增)

v2.2.1 版本 Controller 新增两个方法用于控制引导页的回退,可以在 OnLayoutInflatedListener 接口的回调方法中获取到 controller 对象,执行相应的操作。

.setOnLayoutInflatedListener(new OnLayoutInflatedListener() {@Overridepublic void onLayoutInflated(View view, final Controller controller) {view.findViewById(R.id.btn_ok).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {controller.showPage(0);}});}
})

背景色

引导页的背景色不要在 xml 中设置,通过GuidePage.setBackgroundColor()设置引导页的背景色,不同引导页可以有不同背景色,默认是 0xb2000000,建议设置有透明度的背景色。

anchor

默认的话引导层是添加在 DecorView 中的,我借鉴了Highlight的 anchor 概念,可以改变引导层添加到的 view,实现局部引导层的显示。通过调用.anchor(view)传入 anchorView,即为引导层的根布局。

final View anchorView = findViewById(R.id.ll_anchor);NewbieGuide.with(FirstActivity.this).setLabel("anchor")                        .anchor(anchorView).alwaysShow(true)//总是显示,调试时可以打开.addGuidePage(GuidePage.newInstance()                                .addHighLight(btnAnchor, HighLight.Shape.CIRCLE, 5).setLayoutRes(R.layout.view_guide_anchor)).show();

这里实现了具体显示引导层。

引导层其实是一个 FrameLayout,设置 anchor 之后,引导层的大小就与 anchor 所占的位置相同。默认是 android.R.id.content。setLayoutRes 方法设置的说明布局则会添加到引导层的 FrameLayout 中。

引导层显示隐藏监听

setOnGuideChangedListener 添加引导层的显示隐藏监听,一个 label 表示一个引导层,一个引导层可以有多个引导页,引导页切换不会触发该监听。

NewbieGuide.with(FirstActivity.this).setLabel("listener").alwaysShow(true)//总是显示,调试时可以打开.setOnGuideChangedListener(new OnGuideChangedListener() {@Overridepublic void onShowed(Controller controller) {Toast.makeText(FirstActivity.this, "引导层显示", Toast.LENGTH_SHORT).show();}@Overridepublic void onRemoved(Controller controller) {Toast.makeText(FirstActivity.this, "引导层消失", Toast.LENGTH_SHORT).show();}}).addGuidePage(GuidePage.newInstance().addHighLight(btnListener)).show();

多页引导页与监听

.setOnPageChangedListener(new OnPageChangedListener() {@Overridepublic void onPageChanged(int page) {//引导页切换,page 为当前页位置,从 0 开始Toast.makeText(MainActivity.this, "引导页切换:" + page, Toast.LENGTH_SHORT).show();}
})
.addGuidePage(//添加一页引导页GuidePage.newInstance()//创建一个实例.addHighLight(button)//添加高亮的 view.addHighLight(tvBottom, HighLight.Shape.RECTANGLE).setLayoutRes(R.layout.view_guide)//设置引导页布局.setOnLayoutInflatedListener(new OnLayoutInflatedListener() {@Overridepublic void onLayoutInflated(View view, Controller controller) {//引导页布局填充后回调,用于初始化TextView tv = view.findViewById(R.id.textView2);tv.setText("我是动态设置的文本");}}).setEnterAnimation(enterAnimation)//进入动画.setExitAnimation(exitAnimation)//退出动画)
.addGuidePage(GuidePage.newInstance().addHighLight(tvBottom, HighLight.Shape.RECTANGLE, 20).setLayoutRes(R.layout.view_guide_custom, R.id.iv)//引导页布局,点击跳转下一页或者消失引导层的控件 id.setEverywhereCancelable(false)//是否点击任意地方跳转下一页或者消失引导层,默认 true.setBackgroundColor(getResources().getColor(R.color.testColor))//设置背景色,建议使用有透明度的颜色.setEnterAnimation(enterAnimation)//进入动画.setExitAnimation(exitAnimation)//退出动画)

引导页切换动画

如上面的例子所示,还可以添加引导页的切换动画

Animation enterAnimation = new AlphaAnimation(0f, 1f);
enterAnimation.setDuration(600);
enterAnimation.setFillAfter(true);Animation exitAnimation = new AlphaAnimation(1f, 0f);
exitAnimation.setDuration(600);
exitAnimation.setFillAfter(true);GuidePage.setEnterAnimation(enterAnimation)//进入动画
GuidePage.setExitAnimation(exitAnimation)//退出动画

Q&A

遇到问题可以看查看 Q&A

关于我

Github:https://github.com/huburt-Hu

CSDN:http://blog.csdn.net/Hubert_bing

简书:https://www.jianshu.com/u/002f99a0df6b

掘金:https://juejin.im/user/57bb1fdcc4c971006152d7b0/posts

本人正在考虑新的工作机会,如果有上海的公司,欢迎内推我,联系邮箱 654360340@qq.com 或者微信 h139x726845

License

 Copyright 2017 huburt-HuLicensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Android 快速实现新手引导层的库,通过简洁链式调用,一行代码实现引导层的显示相关推荐

  1. java中链式调用_Java及Android中常用链式调用写法简单示例

    本文实例讲述了Java及Android中常用链式调用写法.分享给大家供大家参考,具体如下: 最近发现,目前大火的许多开源框架中,大多都使用了一种"(方法).(方法).(方法)"的形 ...

  2. Android快速开发框架之xUtils---数据库模块

    本篇博客将介绍一下xUtils的数据库模块,想要学习的小伙伴请先看第一篇注解模块完成第一第二步哦. Android快速开发框架之xUtils-注解模块:http://blog.csdn.net/a_z ...

  3. Android使用MediaPlayer播放流媒体,支持远程以及本地流媒体,一行代码实现

    HDMediaPlayer 该类包依托于谷歌Mediaplayer二次封装,一行代码就可以实现播放的逻辑. 谷歌中国API链接: Google官网API Github地址 https://github ...

  4. 微信小程序手写饼状图,非wx-echarts库,简洁易懂,不占代码体积!!!

    写在前面:小程序也有echarts组件库,但是我觉得太占代码量了,本来小程序的体积只有2m.在下载个组件库.那就没多少了.索性就手写一个. 实现效果: 布局 <view class=" ...

  5. 快速实现免费的个人免签收款功能(不写一行代码)

    最近一直在研究使用冰狐智能辅助的"自动构建"功能在不编程的情况如何实现各种好玩的东东,由于自己利用业余时间开发的小工具需要用到收款功能,于是自然想到用"自动构建" ...

  6. android开发常用组件和第三方库(二)

    TimLiu-Android 自己总结的Android开源项目及库. github排名 https://github.com/trending, github搜索:https://github.com ...

  7. android播放页蒙层过渡效果,EasyGuideLayer: 这可能是最简单、灵活、强大的页面蒙层组件了!...

    原标题:EasyGuideLayer: 这可能是最简单.灵活.强大的页面蒙层组件了! 顾名思义,EasyGuideLayer是用于进行Android页面蒙层引导的组件. 特性 链式调用.调用逻辑清晰直 ...

  8. android 蒙版图片带拖动_推荐一个好用小巧的Android引导蒙版(浮层)库

    更新:目前该库已更新v2.0版本,修改了调用api,详细使用可以看:可能是最好用的Android引导层库 前言 每当一个项目开发一个新功能,总会想办法及时让用户得知有这样一个新功能,这时通常会采用引导 ...

  9. 安卓视频播放器 一行代码快速实现视频播放,Android视频播放,AndroidMP3播放,安卓视频播放一行代码搞定,仿今日头条 Android视频播放器

    一行代码快速实现视频播放,Android视频播放,AndroidMP3播放,安卓视频播放一行代码搞定,真正实现Android的全屏功能 github地址:https://github.com/qius ...

最新文章

  1. 安全攻防技能——Web安全——SQL注入
  2. Aspose.Pdf 系列组件介绍
  3. 210305设计共享内存
  4. 数据的gzip压缩解压缩_使用GZIP和压缩数据
  5. linux分区 挂盘,linux分区,挂盘,LVM
  6. tree(2018.10.26)
  7. 机器学习与计算机视觉(keras和mnist)
  8. 详解 EnumWindows 与 EnumWindowsProc - 回复 SplendourChiang 的问题
  9. 洛谷—— P2251 质量检测
  10. 地震及断层分析相关软件
  11. iOS知识点,iOS开发笔记
  12. kettle 数据库密码解密
  13. cnn风格迁移_CNN图像风格迁移的原理及TensorFlow实现
  14. PySide6精简教程
  15. 官场直升机 鸿蒙笔著,鸿蒙笔会征文一等奖作品 《啼笑缘》续集
  16. html的abbr标签,html标签里有个abbr 请问这个标签是肿么使用的
  17. 从零搭建SSM框架及所遇到问题
  18. [词根词缀]fer/ferv/fid/fig/fin/firm/fix词根由来
  19. matlab之经验分布图
  20. 电机仿真系列-基于LabVIEW的电机测试系统研究

热门文章

  1. 58.什么是深度学习中的anchor
  2. 优雅的PHP采集框架QueryList
  3. 星系超级计算机,超级计算机创造了数以百万计的虚拟宇宙来了解星系的进化
  4. 算法笔记 最大公约数、最小公倍数、素数(质数)
  5. 9月16日数据技术嘉年华成都站,完整议程新鲜出炉
  6. 大数据和人工智能之间,主要有什么区别?
  7. 报录比48:1,上海985同济大学去年计算机考研报录比好高!
  8. 主流消息队列MQ对比
  9. 前端UI框架Ant Design Pro 依赖安装
  10. 【Jedis testOnBorrow配置 引发的生产事故】