今天来推荐一个好用遮罩引导库,这是我持续维护了大半年的开源项目。刚完成初版的时候,我也记录了文章,而且有幸推荐到了郭霖大神的公众号: 推荐一个好用小巧的Android引导蒙版(浮层)库。初版的功能仍是比较简单,在后续的持续迭代中,我也新增了好多新功能:fragment支持,多页连续显示,切换动画,anchor等。如今的2.x版本相比初版,包括调用方式,基本已经彻底不同的。android
若是你看过个人上述文章,就知道我为何建立这个项目。但随着个人特地关注下,发现其实有不少相似的轮子,比较有名的有:GuideView、Highlight、TourGuide等等。我也一一下载了这些项目,学习它们的源码,分析它们的实现。借鉴这些项目以后,我尝试吸收各个项目的优势,不断完善本身的项目,以维护项目的方式让本身成长。git
到目前,这个项目拥有大部分上述项目的功能点,而且使用方式更加简便。具体如何使用仍是看下面的介绍吧~github
项目的build.gradle添加缓存
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
复制代码
module的build.gradle添加bash
dependencies {
compile 'com.github.huburt-Hu:NewbieGuide:v2.0.1'
}
复制代码
若是你的项目中使用了appcompat-v7,能够排除此库对v7的引用,避免版本混淆app
dependencies {
compile ('com.github.huburt-Hu:NewbieGuide:v2.0.0') {
exclude group: 'com.android.support'
}
}
复制代码
NewbieGuide.with(activity)
.setLabel("guide1")
.addGuidePage(GuidePage.newInstance()
.addHighLight(btnSimple)
.setLayoutRes(R.layout.view_guide_simple))
.show();
复制代码
经过链式调用,一行代码便可实现引导层的显示,来看下效果:maven
其中:ide
with
方法能够传入Activity或者Fragment,获取引导页的依附者。Fragment中使用建议传入fragment,内部会添加监听,当依附的Fragment销毁时,引导层自动消失。setLabel
方法用于设置引导页的标签,区别不一样的引导页,该方法必须调用设置,不然会抛出异常。内部使用该label控制引导页的显示次数。addGuidePage
方法添加一页引导页,这里的引导层能够有多个引导页,但至少须要一页。GuidePage
即为引导页对象,表示一页引导页,能够经过.newInstance()
建立对象。并经过addHighLight
添加一个或多个须要高亮的view,该方法有多个重载,能够设置高亮的形状,以及padding等(默认是矩形)。setLayoutRes
方法用于引导页说明布局,就是上图的说明文字的布局。show
方法直接显示引导层,若是不想立刻显示可使用build
方法返回一个Controller对象,完成构建。须要显示得时候再次调用Controller对象的show方法进行显示。一般状况下引导页只在用户首次打开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() {
@Override
public void onLayoutInflated(View view) {
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
)填充完成时会回答调用该监听,用于初始化自定布局的元素。
引导页的背景色不要在xml中设置,经过GuidePage.setBackgroundColor()
设置引导页的背景色,不一样引导页能够有不一样背景色,默认是0xb2000000,建议设置有透明度的背景色。
默认的话引导层是添加在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所占的位置相同。默认是DecorView,即全屏。setLayoutRes方法设置的说明布局则会添加到引导层的FrameLayout中。
setOnGuideChangedListener添加引导层的显示隐藏监听,一个label表示一个引导层,一个引导层能够有多个引导页,引导页切换不会触发该监听。
NewbieGuide.with(FirstActivity.this)
.setLabel("listener")
.alwaysShow(true)//老是显示,调试时能够打开
.setOnGuideChangedListener(new OnGuideChangedListener() {
@Override
public void onShowed(Controller controller) {
Toast.makeText(FirstActivity.this, "引导层显示", Toast.LENGTH_SHORT).show();
}
@Override
public void onRemoved(Controller controller) {
Toast.makeText(FirstActivity.this, "引导层消失", Toast.LENGTH_SHORT).show();
}
})
.addGuidePage(GuidePage.newInstance().addHighLight(btnListener))
.show();
复制代码
.setOnPageChangedListener(new OnPageChangedListener() {
@Override
public 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() {
@Override
public void onLayoutInflated(View view) {
//引导页布局填充后回调,用于初始化
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)//退出动画
复制代码
查看项目的readme