今天來推薦一個好用遮罩引導庫岩调,這是我持續(xù)維護了大半年的開源項目写隶。剛完成第一版的時候衣式,我也記錄了文章,并且有幸推薦到了郭霖大神的公眾號:
推薦一個好用小巧的Android引導蒙版(浮層)庫渤愁。第一版的功能還是比較簡單牵祟,在后續(xù)的持續(xù)迭代中,我也新增了好多新功能:fragment支持猴伶,多頁連續(xù)顯示课舍,切換動畫,anchor等∷妫現(xiàn)在的2.x版本相比第一版,包括調(diào)用方式捡需,基本已經(jīng)完全不一樣的办桨。
如果你看過我的上述文章,就知道我為什么創(chuàng)建這個項目站辉。但隨著我的特意關注下呢撞,發(fā)現(xiàn)其實有很多類似的輪子,比較有名的有:GuideView饰剥、Highlight殊霞、TourGuide等等。我也一一下載了這些項目汰蓉,學習它們的源碼绷蹲,分析它們的實現(xiàn)。借鑒這些項目之后,我嘗試吸取各個項目的優(yōu)點祝钢,不斷完善自己的項目比规,以維護項目的方式讓自己成長。
到目前拦英,這個項目擁有大部分上述項目的功能點蜒什,并且使用方式更加簡便。具體如何使用還是看下面的介紹吧~
項目地址
導入
項目的build.gradle添加
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
module的build.gradle添加
dependencies {
compile 'com.github.huburt-Hu:NewbieGuide:v2.0.1'
}
如果你的項目中使用了appcompat-v7疤估,可以排除此庫對v7的引用灾常,避免版本混淆
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();
通過鏈式調(diào)用,一行代碼即可實現(xiàn)引導層的顯示铃拇,來看下效果:
其中:
-
with
方法可以傳入Activity或者Fragment岗憋,獲取引導頁的依附者。Fragment中使用建議傳入fragment锚贱,內(nèi)部會添加監(jiān)聽仔戈,當依附的Fragment銷毀時,引導層自動消失拧廊。 -
setLabel
方法用于設置引導頁的標簽监徘,區(qū)別不同的引導頁,該方法必須調(diào)用設置吧碾,否則會拋出異常凰盔。內(nèi)部使用該label控制引導頁的顯示次數(shù)。 -
addGuidePage
方法添加一頁引導頁倦春,這里的引導層可以有多個引導頁户敬,但至少需要一頁。 -
GuidePage
即為引導頁對象睁本,表示一頁引導頁尿庐,可以通過.newInstance()
創(chuàng)建對象。并通過addHighLight
添加一個或多個需要高亮的view呢堰,該方法有多個重載抄瑟,可以設置高亮的形狀,以及padding等(默認是矩形)枉疼。setLayoutRes
方法用于引導頁說明布局皮假,就是上圖的說明文字的布局。 -
show
方法直接顯示引導層骂维,如果不想馬上顯示可以使用build
方法返回一個Controller對象惹资,完成構建。需要顯示得時候再次調(diào)用Controller對象的show方法進行顯示航闺。
顯示次數(shù)控制
通常情況下引導頁只在用戶首次打開app的時候顯示褪测,第二次進入時不顯示,因此默認只顯示一次。當然你也可以通過.setShowCounts(3)
自定義顯示的次數(shù)汰扭,調(diào)試的時候可以使用.alwaysShow(true)
設置每次都顯示稠肘。
NewbieGuide.with(activity)
.setLabel("guide1")
//.setShowCounts(3)//控制次數(shù)
.alwaysShow(true)//總是顯示,調(diào)試時可以打開
.addGuidePage(GuidePage.newInstance()
.addHighLight(btnSimple)
.setLayoutRes(R.layout.view_guide_simple))
.show();
就算設置了.alwaysShow(true)
萝毛,內(nèi)部還是會記錄顯示得次數(shù)项阴,之后改會setShowCounts(3)
可能實際記錄的次數(shù)早已超過限制,因此不會再次顯示笆包。使用Controller對象的resetLabel
方法重置次數(shù)环揽。(或者清除應用緩存也能重置次數(shù))
自定義說明布局
著重說明一下setLayoutRes方法,通常其他的類似的庫都是通過代碼參數(shù)來控制說明內(nèi)容展示在高亮view相對的位置庵佣,如下方歉胶。經(jīng)常需要多次運行才能找到滿意的位置的參數(shù)。大多說明內(nèi)容只能出現(xiàn)在高亮的上下左右巴粪,需要庫的支持通今,自定義的程度不是很高。
我所采用的方式是將說明內(nèi)容通過xml的方式肛根,自定義擺放位置辫塌。使得說明內(nèi)容高度自定義,不管你是簡單的圖片派哲,還是對話框類型的都可以臼氨。
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);
}
})
該方法還有一個可變參數(shù)setLayoutRes(@LayoutRes int resId, int... id)
芭届,傳入id數(shù)組表示在布局中點擊讓引導頁消失或者進入下一頁的View(例如储矩,Button ok的id)。
setOnLayoutInflatedListener
設置布局填充完成的監(jiān)聽褂乍,當傳入的xml(R.layout.view_guide_dialog
)填充完成時會回答調(diào)用該監(jiān)聽持隧,用于初始化自定布局的元素。
背景色
引導頁的背景色不要在xml中設置树叽,通過GuidePage.setBackgroundColor()
設置引導頁的背景色舆蝴,不同引導頁可以有不同背景色,默認是0xb2000000题诵,建議設置有透明度的背景色。
anchor
默認的話引導層是添加在DecorView中的层皱,我借鑒了Highlight的anchor概念性锭,可以改變引導層添加到的view,實現(xiàn)局部引導層的顯示叫胖。通過調(diào)用.anchor(view)
傳入anchorView草冈,即為引導層的根布局。
final View anchorView = findViewById(R.id.ll_anchor);
NewbieGuide.with(FirstActivity.this)
.setLabel("anchor") .anchor(anchorView)
.alwaysShow(true)//總是顯示,調(diào)試時可以打開
.addGuidePage(GuidePage.newInstance() .addHighLight(btnAnchor, HighLight.Shape.CIRCLE, 5)
.setLayoutRes(R.layout.view_guide_anchor))
.show();
這里實現(xiàn)了具體顯示引導層怎棱。
引導層其實是一個FrameLayout哩俭,設置anchor之后,引導層的大小就與anchor所占的位置相同拳恋。默認是DecorView凡资,即全屏。setLayoutRes方法設置的說明布局則會添加到引導層的FrameLayout中谬运。
引導層顯示隱藏監(jiān)聽
setOnGuideChangedListener添加引導層的顯示隱藏監(jiān)聽隙赁,一個label表示一個引導層,一個引導層可以有多個引導頁梆暖,引導頁切換不會觸發(fā)該監(jiān)聽伞访。
NewbieGuide.with(FirstActivity.this)
.setLabel("listener")
.alwaysShow(true)//總是顯示,調(diào)試時可以打開
.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();
多頁引導頁與監(jiān)聽
.setOnPageChangedListener(new OnPageChangedListener() {
@Override
public void onPageChanged(int page) {
//引導頁切換轰驳,page為當前頁位置厚掷,從0開始
Toast.makeText(MainActivity.this, "引導頁切換:" + page, Toast.LENGTH_SHORT).show();
}
})
.addGuidePage(//添加一頁引導頁
GuidePage.newInstance()//創(chuàng)建一個實例
.addHighLight(button)//添加高亮的view
.addHighLight(tvBottom, HighLight.Shape.RECTANGLE)
.setLayoutRes(R.layout.view_guide)//設置引導頁布局
.setOnLayoutInflatedListener(new OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(View view) {
//引導頁布局填充后回調(diào),用于初始化
TextView tv = view.findViewById(R.id.textView2);
tv.setText("我是動態(tài)設置的文本");
}
})
.setEnterAnimation(enterAnimation)//進入動畫
.setExitAnimation(exitAnimation)//退出動畫
)
.addGuidePage(
GuidePage.newInstance()
.addHighLight(tvBottom, HighLight.Shape.RECTANGLE, 20)
.setLayoutRes(R.layout.view_guide_custom, R.id.iv)//引導頁布局级解,點擊跳轉(zhuǎn)下一頁或者消失引導層的控件id
.setEverywhereCancelable(false)//是否點擊任意地方跳轉(zhuǎn)下一頁或者消失引導層冒黑,默認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